import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, In } from 'typeorm';
import { KYCVerification } from './entities/kyc-verification.entity';
import { KYCReviewLog } from './entities/kyc-review-log.entity';
import { UsersService } from '../users/users.service';
import { NotificationsService } from '../notifications/notifications.service';
import { ReviewActionDto, ReviewAction } from './dto/review-action.dto';
import { KYCStatus } from '@livebeauty/shared';

@Injectable()
export class KYCReviewService {
  constructor(
    @InjectRepository(KYCVerification)
    private readonly kycRepo: Repository<KYCVerification>,
    @InjectRepository(KYCReviewLog)
    private readonly logRepo: Repository<KYCReviewLog>,
    private readonly usersService: UsersService,
    private readonly notificationsService: NotificationsService,
  ) {}

  async getReviewQueue(status?: string, page = 1, limit = 20): Promise<{ items: KYCVerification[]; total: number }> {
    const where: any = {};

    if (status) {
      where.status = status;
    } else {
      where.status = In([KYCStatus.UNDER_REVIEW, KYCStatus.FLAGGED]);
    }

    const [items, total] = await this.kycRepo.findAndCount({
      where,
      relations: ['documents'],
      order: { submittedAt: 'ASC' },
      skip: (page - 1) * limit,
      take: limit,
    });

    return { items, total };
  }

  async getVerificationDetail(id: string): Promise<KYCVerification> {
    const verification = await this.kycRepo.findOne({
      where: { id },
      relations: ['documents'],
    });

    if (!verification) throw new NotFoundException('Verification not found');
    return verification;
  }

  async reviewKYC(adminId: string, verificationId: string, dto: ReviewActionDto): Promise<KYCVerification> {
    const verification = await this.kycRepo.findOne({
      where: { id: verificationId },
      relations: ['documents'],
    });

    if (!verification) throw new NotFoundException('Verification not found');

    const previousStatus = verification.status;
    let newStatus: KYCStatus;
    let message: string;

    switch (dto.action) {
      case ReviewAction.APPROVE:
        newStatus = KYCStatus.APPROVED;
        message = 'Your identity has been verified! You can now start using the platform.';
        break;
      case ReviewAction.REJECT:
        newStatus = KYCStatus.REJECTED;
        message = `Verification rejected: ${dto.rejectionReason || 'Documents do not meet requirements'}`;
        break;
      case ReviewAction.FLAG:
        newStatus = KYCStatus.FLAGGED;
        message = 'Your verification requires additional review. We will contact you shortly.';
        break;
      case ReviewAction.REQUEST_MORE_INFO:
        newStatus = KYCStatus.PENDING;
        message = `Additional information required: ${dto.notes || 'Please provide more documentation'}`;
        break;
      default:
        throw new NotFoundException('Invalid review action');
    }

    // Update verification
    verification.status = newStatus;
    verification.reviewedBy = adminId;
    verification.reviewedAt = new Date();
    if (dto.action === ReviewAction.REJECT) {
      verification.rejectionReason = dto.rejectionReason;
    }

    await this.kycRepo.save(verification);

    // Create review log
    const log = this.logRepo.create({
      verificationId,
      adminId,
      action: dto.action,
      notes: dto.notes,
      previousStatus,
      newStatus: newStatus as string,
    });
    await this.logRepo.save(log);

    // Update user KYC status
    await this.usersService.updateKYCStatus(verification.userId, newStatus);

    // Notify user
    await this.notificationsService.sendToUser(verification.userId, {
      type: 'kyc_status_update',
      data: { status: newStatus, message },
    });

    return verification;
  }

  async getReviewHistory(verificationId: string): Promise<KYCReviewLog[]> {
    return this.logRepo.find({
      where: { verificationId },
      order: { createdAt: 'DESC' },
    });
  }
}