import { Repository, FindOptionsWhere, ILike } from 'typeorm';
import { Quotation, SalesOrder } from '../entities/index.js';
import { CreateQuotationDto, UpdateQuotationDto, CreateSalesOrderDto, UpdateSalesOrderDto } from '../dto/index.js';

// Export transport-specific service
export * from './ordenes-transporte.service';

/**
 * @deprecated Use ordersService from '../orders.service.js' for full Order-to-Cash flow
 * This TypeORM-based service provides basic CRUD operations.
 * For advanced features (stock reservation, auto-picking, delivery tracking),
 * use the SQL-based ordersService instead.
 */
export interface SalesSearchParams {
  tenantId: string;
  search?: string;
  partnerId?: string;
  status?: string;
  userId?: string; // Changed from salesRepId to match entity
  fromDate?: Date;
  toDate?: Date;
  limit?: number;
  offset?: number;
}

/**
 * @deprecated Use ordersService from '../orders.service.js' for full Order-to-Cash flow
 */
export class SalesService {
  constructor(
    private readonly quotationRepository: Repository<Quotation>,
    private readonly orderRepository: Repository<SalesOrder>
  ) {}

  async findAllQuotations(params: SalesSearchParams): Promise<{ data: Quotation[]; total: number }> {
    const { tenantId, search, partnerId, status, userId, limit = 50, offset = 0 } = params;
    const where: FindOptionsWhere<Quotation> = { tenantId };
    if (partnerId) where.partnerId = partnerId;
    if (status) where.status = status as any;
    if (userId) where.salesRepId = userId;
    const [data, total] = await this.quotationRepository.findAndCount({ where, take: limit, skip: offset, order: { createdAt: 'DESC' } });
    return { data, total };
  }

  async findQuotation(id: string, tenantId: string): Promise<Quotation | null> {
    return this.quotationRepository.findOne({ where: { id, tenantId } });
  }

  async createQuotation(tenantId: string, dto: CreateQuotationDto, createdBy?: string): Promise<Quotation> {
    const count = await this.quotationRepository.count({ where: { tenantId } });
    const quotationNumber = `COT-${String(count + 1).padStart(6, '0')}`;
    const quotation = this.quotationRepository.create({ ...dto, tenantId, quotationNumber, createdBy, quotationDate: dto.quotationDate ? new Date(dto.quotationDate) : new Date(), validUntil: dto.validUntil ? new Date(dto.validUntil) : undefined });
    return this.quotationRepository.save(quotation);
  }

  async updateQuotation(id: string, tenantId: string, dto: UpdateQuotationDto, updatedBy?: string): Promise<Quotation | null> {
    const quotation = await this.findQuotation(id, tenantId);
    if (!quotation) return null;
    Object.assign(quotation, { ...dto, updatedBy });
    return this.quotationRepository.save(quotation);
  }

  async deleteQuotation(id: string, tenantId: string): Promise<boolean> {
    const result = await this.quotationRepository.softDelete({ id, tenantId });
    return (result.affected ?? 0) > 0;
  }

  /**
   * @deprecated Use ordersService.confirm() for proper picking and stock flow
   */
  async convertQuotationToOrder(id: string, tenantId: string, userId?: string): Promise<SalesOrder> {
    const quotation = await this.findQuotation(id, tenantId);
    if (!quotation) throw new Error('Quotation not found');
    if (quotation.convertedToOrder) throw new Error('Quotation already converted');

    const order = await this.createSalesOrder(tenantId, {
      partnerId: quotation.partnerId,
      quotationId: quotation.id,
      notes: quotation.notes,
    }, userId);

    quotation.convertedToOrder = true;
    quotation.orderId = order.id;
    quotation.convertedAt = new Date();
    quotation.status = 'converted';
    await this.quotationRepository.save(quotation);

    return order;
  }

  async findAllOrders(params: SalesSearchParams): Promise<{ data: SalesOrder[]; total: number }> {
    const { tenantId, search, partnerId, status, userId, limit = 50, offset = 0 } = params;
    const where: FindOptionsWhere<SalesOrder> = { tenantId };
    if (partnerId) where.partnerId = partnerId;
    if (status) where.status = status as any;
    if (userId) where.userId = userId;
    const [data, total] = await this.orderRepository.findAndCount({ where, take: limit, skip: offset, order: { createdAt: 'DESC' } });
    return { data, total };
  }

  async findOrder(id: string, tenantId: string): Promise<SalesOrder | null> {
    return this.orderRepository.findOne({ where: { id, tenantId } });
  }

  /**
   * @deprecated Use ordersService.create() for proper sequence generation
   */
  async createSalesOrder(tenantId: string, dto: CreateSalesOrderDto, createdBy?: string): Promise<SalesOrder> {
    const count = await this.orderRepository.count({ where: { tenantId } });
    const orderName = `SO-${String(count + 1).padStart(6, '0')}`;
    const orderData: Partial<SalesOrder> = {
      tenantId,
      companyId: (dto as any).companyId || '00000000-0000-0000-0000-000000000000',
      name: orderName,
      partnerId: dto.partnerId,
      quotationId: dto.quotationId || null,
      currencyId: (dto as any).currencyId || '00000000-0000-0000-0000-000000000000',
      orderDate: new Date(),
      commitmentDate: dto.promisedDate ? new Date(dto.promisedDate) : null,
      notes: dto.notes || null,
      createdBy: createdBy || null,
    };
    const order = this.orderRepository.create(orderData as SalesOrder);
    return this.orderRepository.save(order);
  }

  async updateSalesOrder(id: string, tenantId: string, dto: UpdateSalesOrderDto, updatedBy?: string): Promise<SalesOrder | null> {
    const order = await this.findOrder(id, tenantId);
    if (!order) return null;
    if (dto.notes !== undefined) order.notes = dto.notes || null;
    order.updatedBy = updatedBy || null;
    return this.orderRepository.save(order);
  }

  async deleteSalesOrder(id: string, tenantId: string): Promise<boolean> {
    const result = await this.orderRepository.softDelete({ id, tenantId });
    return (result.affected ?? 0) > 0;
  }

  /**
   * @deprecated Use ordersService.confirm() for proper picking and stock reservation
   */
  async confirmOrder(id: string, tenantId: string, userId?: string): Promise<SalesOrder | null> {
    const order = await this.findOrder(id, tenantId);
    if (!order || order.status !== 'draft') return null;
    order.status = 'sent'; // Changed from 'confirmed' to match entity enum
    order.updatedBy = userId || null;
    return this.orderRepository.save(order);
  }

  /**
   * @deprecated Use pickings validation flow for proper delivery tracking
   */
  async shipOrder(id: string, tenantId: string, _trackingNumber?: string, _carrier?: string, userId?: string): Promise<SalesOrder | null> {
    const order = await this.findOrder(id, tenantId);
    if (!order || order.status !== 'sent') return null;
    order.status = 'sale';
    order.deliveryStatus = 'partial';
    order.updatedBy = userId || null;
    return this.orderRepository.save(order);
  }

  /**
   * @deprecated Use pickings validation flow for proper delivery tracking
   */
  async deliverOrder(id: string, tenantId: string, userId?: string): Promise<SalesOrder | null> {
    const order = await this.findOrder(id, tenantId);
    if (!order || order.status !== 'sale') return null;
    order.status = 'done';
    order.deliveryStatus = 'delivered';
    order.updatedBy = userId || null;
    return this.orderRepository.save(order);
  }
}

export { SalesService as default };
