import { Body, Controller, Delete, Get, Inject, Param, Post, UseGuards } from "@nestjs/common";
import type Redis from "ioredis";
import {
  DeleteDraftRequest,
  EntityId,
  UpdateNotificationPreferencesRequest,
  UpsertDraftRequest,
} from "@slackwsh/contracts";
import * as messaging from "@slackwsh/messaging";
import { AuthGuard } from "../auth/auth.guard";
import { CurrentUser } from "../auth/current-user.decorator";
import type { RequestUser } from "../auth/auth.guard";
import { REDIS_PUBSUB } from "../common/redis-pubsub.provider";

@UseGuards(AuthGuard)
@Controller("workspaces/:workspaceId/state")
export class PersonalStateController {
  constructor(@Inject(REDIS_PUBSUB) private readonly redis: Redis) {}

  @Get("notification-preferences")
  async notificationPreferences(@CurrentUser() user: RequestUser, @Param("workspaceId") workspaceId: string) {
    return { preferences: await messaging.getNotificationPreferences(workspaceId, user.userId) };
  }

  @Post("notification-preferences")
  async updateNotificationPreferences(
    @CurrentUser() user: RequestUser,
    @Param("workspaceId") workspaceId: string,
    @Body() body: unknown,
  ) {
    const input = UpdateNotificationPreferencesRequest.parse(body);
    return { preferences: await messaging.updateNotificationPreferences(this.redis, workspaceId, user.userId, input) };
  }

  @Get("saved-items")
  async savedItems(@CurrentUser() user: RequestUser, @Param("workspaceId") workspaceId: string) {
    return { items: await messaging.listSavedItems(workspaceId, user.userId) };
  }

  @Post("saved-items/:messageId")
  async save(
    @CurrentUser() user: RequestUser,
    @Param("workspaceId") workspaceId: string,
    @Param("messageId") messageId: string,
  ) {
    await messaging.saveItem(this.redis, workspaceId, user.userId, EntityId.parse(messageId));
    return { saved: true };
  }

  @Delete("saved-items/:messageId")
  async unsave(
    @CurrentUser() user: RequestUser,
    @Param("workspaceId") workspaceId: string,
    @Param("messageId") messageId: string,
  ) {
    await messaging.unsaveItem(this.redis, workspaceId, user.userId, EntityId.parse(messageId));
    return { saved: false };
  }

  @Get("drafts")
  async drafts(@CurrentUser() user: RequestUser, @Param("workspaceId") workspaceId: string) {
    return { drafts: await messaging.listDrafts(workspaceId, user.userId) };
  }

  @Post("drafts")
  async upsertDraft(
    @CurrentUser() user: RequestUser,
    @Param("workspaceId") workspaceId: string,
    @Body() body: unknown,
  ) {
    const input = UpsertDraftRequest.parse(body);
    return { draft: await messaging.upsertDraft(this.redis, workspaceId, user.userId, input) };
  }

  @Post("drafts/delete")
  async deleteDraft(
    @CurrentUser() user: RequestUser,
    @Param("workspaceId") workspaceId: string,
    @Body() body: unknown,
  ) {
    const input = DeleteDraftRequest.parse(body);
    await messaging.deleteDraft(this.redis, workspaceId, user.userId, input);
    return { deleted: true };
  }
}
