import { InternalServerErrorException } from '@nestjs/common';
import { CommandHandler, type ICommandHandler } from '@nestjs/cqrs';
import { type Prisma } from '@prisma/client';
import { DomainException, ForbiddenException, NotFoundException, ValidationException, PrismaService, LoggerService } from '@modules/shared';
import { UpdateSavedSearchCommand } from './update-saved-search.command';

export interface UpdateSavedSearchResult {
  id: string;
  name: string;
  filters: unknown;
  alertEnabled: boolean;
  createdAt: Date;
}

@CommandHandler(UpdateSavedSearchCommand)
export class UpdateSavedSearchHandler implements ICommandHandler<UpdateSavedSearchCommand> {
  constructor(
    private readonly prisma: PrismaService,
    private readonly logger: LoggerService,
  ) {}

  async execute(command: UpdateSavedSearchCommand): Promise<UpdateSavedSearchResult> {
    try {
      const savedSearch = await this.prisma.savedSearch.findUnique({
        where: { id: command.id },
      });

      if (!savedSearch) {
        throw new NotFoundException('SavedSearch', command.id);
      }

      if (savedSearch.userId !== command.userId) {
        throw new ForbiddenException('Bạn không có quyền cập nhật tìm kiếm này');
      }

      if (command.name !== undefined && command.name.trim().length === 0) {
        throw new ValidationException('Tên tìm kiếm không được để trống');
      }

      if (command.name !== undefined && command.name.trim().length > 100) {
        throw new ValidationException('Tên tìm kiếm không được vượt quá 100 ký tự');
      }

      const updated = await this.prisma.savedSearch.update({
        where: { id: command.id },
        data: {
          ...(command.name !== undefined && { name: command.name.trim() }),
          ...(command.filters !== undefined && { filters: command.filters as Prisma.InputJsonValue }),
          ...(command.alertEnabled !== undefined && { alertEnabled: command.alertEnabled }),
        },
      });

      this.logger.log(`Saved search updated: id=${command.id}, user=${command.userId}`, 'UpdateSavedSearchHandler');

      return {
        id: updated.id,
        name: updated.name,
        filters: updated.filters,
        alertEnabled: updated.alertEnabled,
        createdAt: updated.createdAt,
      };
    } catch (error) {
      if (error instanceof DomainException) throw error;
      this.logger.error(
        `Failed to update saved search: ${error instanceof Error ? error.message : error}`,
        error instanceof Error ? error.stack : undefined,
        this.constructor.name,
      );
      throw new InternalServerErrorException('Không thể cập nhật tìm kiếm đã lưu');
    }
  }
}
