import { InternalServerErrorException } from '@nestjs/common';
import { CommandHandler, type ICommandHandler } from '@nestjs/cqrs';
import { LoggerService, PrismaService, DomainException, NotFoundException } from '@modules/shared';
import { ExportUserDataCommand } from './export-user-data.command';

export interface UserDataExport {
  user: {
    id: string;
    email: string | null;
    phone: string;
    fullName: string;
    role: string;
    kycStatus: string;
    createdAt: Date;
  };
  agent: unknown | null;
  listings: unknown[];
  payments: unknown[];
  subscription: unknown | null;
  reviews: unknown[];
  inquiries: unknown[];
  savedSearches: unknown[];
  transactions: unknown[];
  exportedAt: string;
}

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

  async execute(command: ExportUserDataCommand): Promise<UserDataExport> {
    try {
      const user = await this.prisma.user.findUnique({
        where: { id: command.userId },
        select: {
          id: true, email: true, phone: true, fullName: true,
          role: true, kycStatus: true, createdAt: true,
        },
      });

      if (!user) throw new NotFoundException('User', command.userId);

      const [agent, listings, payments, subscription, reviews, inquiries, savedSearches, transactions] =
        await Promise.all([
          this.prisma.agent.findUnique({ where: { userId: command.userId } }),
          this.prisma.listing.findMany({
            where: { sellerId: command.userId },
            include: { property: { select: { title: true, address: true, district: true, city: true } } },
          }),
          this.prisma.payment.findMany({
            where: { userId: command.userId },
            select: { id: true, provider: true, type: true, amountVND: true, status: true, createdAt: true },
          }),
          this.prisma.subscription.findFirst({ where: { userId: command.userId } }),
          this.prisma.review.findMany({ where: { userId: command.userId } }),
          this.prisma.inquiry.findMany({ where: { userId: command.userId } }),
          this.prisma.savedSearch.findMany({ where: { userId: command.userId } }),
          this.prisma.transaction.findMany({ where: { buyerId: command.userId } }),
        ]);

      this.logger.log(`User data exported for ${command.userId}`, 'ExportUserDataHandler');

      return {
        user,
        agent,
        listings,
        payments,
        subscription,
        reviews,
        inquiries,
        savedSearches,
        transactions,
        exportedAt: new Date().toISOString(),
      };
    } catch (error) {
      if (error instanceof DomainException) throw error;
      this.logger.error(
        `Failed to export user data: ${error instanceof Error ? error.message : error}`,
        error instanceof Error ? error.stack : undefined,
        this.constructor.name,
      );
      throw new InternalServerErrorException('Không thể xuất dữ liệu người dùng');
    }
  }
}
