// Tipos del modulo fiscal. Ojo con la frontera: aca NO entran tipos de Gustito.
// Gustito manda una VENTA (lo que se vendio y cuanto se cobro) y este modulo la
// convierte en un DOCUMENTO FISCAL, lo sella y lo resguarda.

/** Lo que Gustito (o el Cerebrito) le entrega al modulo: una venta ya cerrada. */
export interface VentaEntrante {
  /** Id de la venta en el sistema de origen, para no procesar dos veces la misma. */
  origen_id: string;
  /** De donde viene: sirve para el reporte, no cambia el calculo. */
  canal: 'mesa' | 'delivery' | 'pickup' | 'caja';
  cliente: {
    nombre: string;
    rif?: string | null;
    cedula?: string | null;
    direccion?: string | null;
  };
  renglones: {
    nombre: string;
    cantidad: number;
    /** Precio unitario tal como se le cobro al cliente. */
    precio_usd: number;
    /** Alicuota que le toca a ese renglon (16, 8, 0). */
    alicuota: number;
  }[];
  /** Cargos que no son productos (delivery, servicio). Van gravados igual. */
  otros_cargos?: { nombre: string; monto_usd: number; alicuota: number }[];
  /** Tasa del dia, para expresar el documento tambien en bolivares. */
  tasa_bs: number | null;
  /**
   * Como pago el cliente (informativo para el documento). `en_divisas` importa
   * SOLO si el emisor es agente de percepcion del IGTF: marca que el pago fue
   * en moneda extranjera (efectivo en dolares, zelle). Si no viene, solo zelle
   * se asume divisa; el efectivo NO se adivina.
   */
  pago?: { metodo: string; referencia?: string | null; en_divisas?: boolean } | null;
}

/** Un renglon ya calculado: base, impuesto y total, congelados. */
export interface RenglonFiscal {
  nombre: string;
  cantidad: number;
  precio_usd: number;
  alicuota: number;
  base_usd: number;
  iva_usd: number;
  total_usd: number;
}

/** El documento fiscal armado: esto es lo que se sella y se transmite. */
export interface DocumentoFiscal {
  tipo: TipoDocumento;
  emisor: {
    rif: string;
    razon_social: string;
    domicilio_fiscal: string;
  };
  cliente: VentaEntrante['cliente'];
  canal: VentaEntrante['canal'];
  renglones: RenglonFiscal[];
  /** Totales por alicuota, para el desglose que exige el documento. */
  por_alicuota: { alicuota: number; base_usd: number; iva_usd: number }[];
  base_usd: number;
  iva_usd: number;
  total_usd: number;
  tasa_bs: number | null;
  total_bs: number | null;
  /**
   * IGTF (3% sobre pagos en divisas). Presente SOLO si el emisor fue designado
   * agente de percepcion (Providencia 000013) y activo el modulo, y el pago fue
   * en divisas. Va APARTE del total de la venta: es un cargo que se percibe.
   */
  igtf_usd?: number;
  pago: VentaEntrante['pago'];
  origen_id: string;
  /** Solo en notas: por que se corrigio. La norma exige que conste el motivo. */
  motivo?: string;
  /**
   * Solo en las facturas del talonario manual (contingencia): el numero que ya
   * venia impreso en el papel y cuando se emitio de verdad. La estacion NO le
   * pone numero a esas: solo las anota para que el reporte del mes no quede con
   * un hueco del tamaño del apagon.
   */
  talonario?: { numero: string; emitido_en: string };
}

export type TipoDocumento = 'factura' | 'nota_credito' | 'nota_debito' | 'factura_manual';

/** Una linea del libro. Se escribe UNA vez y no se toca nunca mas. */
export interface Asiento {
  /** Correlativo del LIBRO: cuenta todo lo asentado, sin importar el tipo. */
  seq: number;
  /** Serie del documento (una por instalacion, no se mezcla). */
  serie: string;
  /** Correlativo del DOCUMENTO por tipo: facturas 1,2,3; notas 1,2,3. */
  numero: number;
  /** Numero de control: consecutivo unico para TODOS los documentos. */
  control: number;
  tipo: TipoDocumento;
  documento: DocumentoFiscal;
  /** Si es una nota, a que documento corrige. Nunca se edita el original. */
  ref?: { serie: string; tipo: TipoDocumento; numero: number } | null;
  /** Momento del sellado, en hora del equipo. */
  sellado_en: string;
  /** Equipo que sello (una instalacion, un RIF). */
  equipo: string;
  /** Estado de la transmision al SENIAT. Vive APARTE del hash: cambia. */
  hash_anterior: string;
  hash: string;
}

/** Evento de la bitacora: quien, que, cuando y desde donde. */
export interface Evento {
  seq: number;
  en: string;
  quien: string;
  desde: string;
  accion: string;
  detalle?: Record<string, unknown>;
  hash_anterior: string;
  hash: string;
}
