import { apiClient } from './client';

export interface OrgStatus {
  configured: boolean;
  orgId?: string;
  legalName?: string;
  hasCsd?: boolean;
}

export interface TimbreStatus {
  configured: boolean;
  // Backward compat (flat fields representan el pool mensual)
  tipo?: string;
  limite?: number;
  usados?: number;
  disponibles?: number;
  periodoFin?: string;
  // Shape extendido
  mensual?: {
    tipo: string;
    limite: number;
    usados: number;
    disponibles: number;
    periodoFin: string;
  };
  adicionales?: {
    total: number;
    usados: number;
    disponibles: number;
    paquetes: Array<{
      id: number;
      cantidad: number;
      usados: number;
      disponibles: number;
      adquiridoEn: string;
      expiraEn: string;
    }>;
  };
  totalDisponibles?: number;
}

export interface InvoiceCustomer {
  legalName: string;
  taxId: string;
  taxSystem: string;
  email?: string;
  zip: string;
}

export interface InvoiceLineItem {
  description: string;
  productKey: string;
  unitKey?: string;
  unitName?: string;
  quantity: number;
  price: number;
  taxIncluded?: boolean;
  taxes?: Array<{ type: string; rate: number }>;
}

export interface InvoiceData {
  customer: InvoiceCustomer;
  items: InvoiceLineItem[];
  use: string;
  paymentForm: string;
  paymentMethod?: string;
  currency?: string;
  exchangeRate?: number;
  series?: string;
  folioNumber?: number;
  conditions?: string;
  fechaEmision?: string;
  cuentaPredial?: string;
}

export interface InvoiceResult {
  id: string;
  uuid: string;
  total: number;
  status: string;
}

export const getOrgStatus = () => apiClient.get<OrgStatus>('/facturacion/org/status').then(r => r.data);
export const createOrg = () => apiClient.post('/facturacion/org').then(r => r.data);
export const uploadCsd = (data: { cerFile: string; keyFile: string; password: string }) =>
  apiClient.post('/facturacion/csd', data).then(r => r.data);
export const getTimbres = () => apiClient.get<TimbreStatus>('/facturacion/timbres').then(r => r.data);

export interface PaqueteCatalogo {
  id: number;
  cantidad: number;
  precio: number;
}

export const getPaquetesCatalogo = () =>
  apiClient.get<PaqueteCatalogo[]>('/facturacion/timbres/paquetes-catalogo').then(r => r.data);

export const comprarPaquete = (catalogoId: number) =>
  apiClient.post<{ paymentId: string; checkoutUrl: string }>('/facturacion/timbres/paquetes/comprar', { catalogoId })
    .then(r => r.data);

export interface PaqueteCatalogoAdmin {
  id: number;
  cantidad: number;
  precio: number;
  active: boolean;
  updatedAt: string;
}

export const getPaquetesCatalogoAdmin = () =>
  apiClient.get<PaqueteCatalogoAdmin[]>('/facturacion/timbres/paquetes-catalogo/admin').then(r => r.data);

export const updatePaqueteCatalogo = (id: number, data: { precio?: number; active?: boolean }) =>
  apiClient.put<PaqueteCatalogoAdmin>(`/facturacion/timbres/paquetes-catalogo/${id}`, data).then(r => r.data);
export const emitirFactura = (data: InvoiceData) =>
  apiClient.post<InvoiceResult>('/facturacion/emitir', data).then(r => r.data);
export const cancelarFactura = (uuid: string, motive?: string, substitution?: string, contribuyenteId?: string) =>
  apiClient.post(`/facturacion/cancelar/${uuid}`, { motive, substitution, contribuyenteId }).then(r => r.data);
export const downloadPdf = (id: string) =>
  apiClient.get(`/facturacion/pdf/${id}`, { responseType: 'blob' }).then(r => r.data);
export const downloadXml = (id: string) =>
  apiClient.get(`/facturacion/xml/${id}`, { responseType: 'blob' }).then(r => r.data);

export interface RfcSearchResult {
  id: number;
  rfc: string;
  razonSocial: string | null;
  regimenFiscal: string | null;
  codigoPostal: string | null;
}

export const searchRfcs = (q: string, contribuyenteId?: string) => {
  const params = new URLSearchParams({ q });
  if (contribuyenteId) params.set('contribuyenteId', contribuyenteId);
  return apiClient.get<RfcSearchResult[]>(`/facturacion/rfcs/search?${params.toString()}`).then(r => r.data);
};

export interface CfdiPpdPendiente {
  uuid: string;
  serie: string | null;
  folio: string | null;
  totalMxn: number;
  fechaEmision: string;
  rfcReceptor: string;
  nombreReceptor: string;
  ivaTrasladoMxn: number;
  saldoPendiente: number;
}

export const getCfdisPpd = (rfc: string, contribuyenteId?: string) => {
  const params = new URLSearchParams({ rfc });
  if (contribuyenteId) params.set('contribuyenteId', contribuyenteId);
  return apiClient.get<CfdiPpdPendiente[]>(`/facturacion/cfdis-ppd?${params.toString()}`).then(r => r.data);
};

export interface CfdiRelacionable {
  uuid: string;
  serie: string | null;
  folio: string | null;
  totalMxn: number;
  fechaEmision: string;
  tipoComprobante: 'I' | 'E';
  metodoPago: string | null;
}

export const getCfdisRelacionables = (rfcReceptor: string, contribuyenteId: string) =>
  apiClient
    .get<CfdiRelacionable[]>(
      `/facturacion/cfdis-relacionables?rfcReceptor=${encodeURIComponent(rfcReceptor)}&contribuyenteId=${encodeURIComponent(contribuyenteId)}`,
    )
    .then(r => r.data);

export interface ConceptoPrevio {
  claveProdServ: string;
  descripcion: string;
  claveUnidad: string | null;
  unidad: string | null;
  valorUnitario: number;
  importe: number;
  ivaTraslado: number;
  isrRetencion: number;
  ivaRetencion: number;
  tipoCfdi: string;
  rfcEmisor: string;
  nombreEmisor: string;
  rfcReceptor: string;
  nombreReceptor: string;
  fechaEmision: string;
}

export const getPagosSinFactura = () =>
  apiClient.get<Array<{
    id: string;
    tenantId: string;
    amount: string;
    status: string;
    paymentMethod: string | null;
    paidAt: string | null;
    createdAt: string;
    kind: string;
    subscription: { plan: string; frequency: string } | null;
    tenant: { nombre: string; rfc: string | null };
  }>>('/facturacion/pagos-sin-factura').then(r => r.data);

export const emitirFacturaPago = (paymentId: string) =>
  apiClient.post<{ success: boolean; invoiceId: string; paymentId: string }>(`/facturacion/emitir-factura-pago/${paymentId}`).then(r => r.data);

export const searchConceptos = (q: string, tipo?: string, contribuyenteId?: string | null) => {
  const params = new URLSearchParams();
  if (q) params.set('q', q);
  if (tipo) params.set('tipo', tipo);
  if (contribuyenteId) params.set('contribuyenteId', contribuyenteId);
  return apiClient.get<ConceptoPrevio[]>(`/facturacion/conceptos/search?${params}`).then(r => r.data);
};
