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

interface CreateQuoteData {
  dealId: string;
  items: any[];
  subtotal: number;
  discountType?: string;
  discountValue?: number;
  taxRate: number;
  taxAmount: number;
  total: number;
  validUntil: Date;
  paymentTerms?: string;
  deliveryTerms?: string;
  notes?: string;
}

class QuotesService {
  async create(data: CreateQuoteData, userId: string) {
    // Get latest version for this deal
    const latestQuote = await prisma.quote.findFirst({
      where: { dealId: data.dealId },
      orderBy: { version: 'desc' },
      select: { version: true },
    });

    const version = latestQuote ? latestQuote.version + 1 : 1;

    // Generate quote number
    const quoteNumber = await this.generateQuoteNumber();

    const quote = await prisma.quote.create({
      data: {
        quoteNumber,
        dealId: data.dealId,
        version,
        items: data.items,
        subtotal: data.subtotal,
        discountType: data.discountType,
        discountValue: data.discountValue,
        taxRate: data.taxRate,
        taxAmount: data.taxAmount,
        total: data.total,
        validUntil: data.validUntil,
        paymentTerms: data.paymentTerms,
        deliveryTerms: data.deliveryTerms,
        notes: data.notes,
      },
      include: {
        deal: {
          include: {
            contact: true,
          },
        },
      },
    });

    await AuditLogger.log({
      entityType: 'QUOTE',
      entityId: quote.id,
      action: 'CREATE',
      userId,
    });

    return quote;
  }

  async findById(id: string) {
    const quote = await prisma.quote.findUnique({
      where: { id },
      include: {
        deal: {
          include: {
            contact: true,
            owner: true,
          },
        },
      },
    });

    if (!quote) {
      throw new AppError(404, 'عرض السعر غير موجود - Quote not found');
    }

    return quote;
  }

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

  async updateStatus(id: string, status: string, userId: string) {
    const quote = await prisma.quote.update({
      where: { id },
      data: { status },
      include: {
        deal: true,
      },
    });

    await AuditLogger.log({
      entityType: 'QUOTE',
      entityId: quote.id,
      action: 'STATUS_CHANGE',
      userId,
      changes: { status },
    });

    return quote;
  }

  async approve(id: string, approvedBy: string, userId: string) {
    const quote = await prisma.quote.update({
      where: { id },
      data: {
        status: 'APPROVED',
        approvedBy,
        approvedAt: new Date(),
      },
      include: {
        deal: {
          include: {
            owner: true,
          },
        },
      },
    });

    await AuditLogger.log({
      entityType: 'QUOTE',
      entityId: quote.id,
      action: 'APPROVE',
      userId,
      changes: { approvedBy },
    });

    // Create notification
    await prisma.notification.create({
      data: {
        userId: quote.deal.ownerId,
        type: 'QUOTE_APPROVED',
        title: 'تمت الموافقة على عرض السعر - Quote Approved',
        message: `تمت الموافقة على عرض السعر رقم ${quote.quoteNumber}`,
        entityType: 'QUOTE',
        entityId: quote.id,
      },
    });

    return quote;
  }

  async markAsSent(id: string, userId: string) {
    const quote = await prisma.quote.update({
      where: { id },
      data: {
        status: 'SENT',
        sentAt: new Date(),
      },
    });

    await AuditLogger.log({
      entityType: 'QUOTE',
      entityId: quote.id,
      action: 'SEND',
      userId,
    });

    return quote;
  }

  private async generateQuoteNumber(): Promise<string> {
    const year = new Date().getFullYear();
    const prefix = `QT-${year}-`;
    
    const lastQuote = await prisma.quote.findFirst({
      where: {
        quoteNumber: {
          startsWith: prefix,
        },
      },
      orderBy: {
        createdAt: 'desc',
      },
      select: {
        quoteNumber: true,
      },
    });

    let nextNumber = 1;
    if (lastQuote) {
      const lastNumber = parseInt(lastQuote.quoteNumber.split('-')[2]);
      nextNumber = lastNumber + 1;
    }

    return `${prefix}${nextNumber.toString().padStart(6, '0')}`;
  }
}

export const quotesService = new QuotesService();

