import prisma from '../../config/database';
import { AppError } from '../../shared/middleware/errorHandler';
import { AuditLogger } from '../../shared/utils/auditLogger';

interface CreateCostSheetData {
  dealId: string;
  items: any[];
  totalCost: number;
  suggestedPrice: number;
  profitMargin: number;
}

class CostSheetsService {
  async create(data: CreateCostSheetData, userId: string) {
    const latest = await prisma.costSheet.findFirst({
      where: { dealId: data.dealId },
      orderBy: { version: 'desc' },
      select: { version: true },
    });
    const version = latest ? latest.version + 1 : 1;
    const costSheetNumber = await this.generateCostSheetNumber();

    const costSheet = await prisma.costSheet.create({
      data: {
        costSheetNumber,
        dealId: data.dealId,
        version,
        items: data.items,
        totalCost: data.totalCost,
        suggestedPrice: data.suggestedPrice,
        profitMargin: data.profitMargin,
        status: 'DRAFT',
      },
      include: {
        deal: { include: { contact: true, owner: true } },
      },
    });

    await AuditLogger.log({
      entityType: 'COST_SHEET',
      entityId: costSheet.id,
      action: 'CREATE',
      userId,
    });
    return costSheet;
  }

  async findById(id: string) {
    const cs = await prisma.costSheet.findUnique({
      where: { id },
      include: {
        deal: { include: { contact: true, owner: true } },
      },
    });
    if (!cs) throw new AppError(404, 'كشف التكلفة غير موجود - Cost sheet not found');
    return cs;
  }

  async findByDeal(dealId: string) {
    return prisma.costSheet.findMany({
      where: { dealId },
      orderBy: { version: 'desc' },
    });
  }

  async approve(id: string, approvedBy: string, userId: string) {
    const cs = await prisma.costSheet.update({
      where: { id },
      data: { status: 'APPROVED', approvedBy, approvedAt: new Date() },
      include: { deal: true },
    });
    await AuditLogger.log({
      entityType: 'COST_SHEET',
      entityId: id,
      action: 'APPROVE',
      userId,
    });
    return cs;
  }

  async reject(id: string, userId: string) {
    const cs = await prisma.costSheet.update({
      where: { id },
      data: { status: 'REJECTED', approvedBy: null, approvedAt: null },
      include: { deal: true },
    });
    await AuditLogger.log({
      entityType: 'COST_SHEET',
      entityId: id,
      action: 'REJECT',
      userId,
    });
    return cs;
  }

  private async generateCostSheetNumber(): Promise<string> {
    const year = new Date().getFullYear();
    const prefix = `CS-${year}-`;
    const last = await prisma.costSheet.findFirst({
      where: { costSheetNumber: { startsWith: prefix } },
      orderBy: { createdAt: 'desc' },
      select: { costSheetNumber: true },
    });
    let next = 1;
    if (last) {
      const parts = last.costSheetNumber.split('-');
      next = parseInt(parts[2] || '0') + 1;
    }
    return `${prefix}${next.toString().padStart(6, '0')}`;
  }
}

export const costSheetsService = new CostSheetsService();
