import { db } from './db';
import { formatCurrency } from './utils';

function normalize(value: any): string {
  return String(value || '').trim().toLowerCase();
}

function sortOtsDesc(items: any[]) {
  return items.slice().sort((a, b) => new Date(b.fechaEntrada).getTime() - new Date(a.fechaEntrada).getTime());
}

function mapVehiculo(row: any) {
  return {
    id: row.serverId || `local-${row.localId}`,
    placa: row.placa,
    marca: row.marca,
    modelo: row.modelo,
    anio: row.anio,
    color: row.color,
    motor: row.motor,
    cilindraje: row.cilindraje,
  };
}

function mapOt(ot: any) {
  const totalCotizacion = Number(ot?.cotizacion?.total || 0);
  const routeId = ot.serverId ? String(ot.serverId) : `local-${ot.localId}`;
  const fotos = ot.fotos || [];
  const danos = ot.danos || [];

  return {
    id: routeId,
    numeroOt: ot.numeroOt || `OT-LOCAL-${String(ot.localId).slice(0, 8).toUpperCase()}`,
    estado: ot.estado,
    fechaEntrada: ot.fechaEntrada,
    fechaSalida: ot.fechaSalida,
    km: ot.km,
    totalCotizacion,
    requerimientoCliente: ot.requerimientoCliente,
    observaciones: ot.observaciones,
    vehiculo: ot.vehiculo || {},
    cotizacion: ot.cotizacion || null,
    evidencia: {
      fotos,
      danos,
      firmaCliente: ot.firma?.firmaCliente || null,
      firmaRecepcion: ot.firma?.firmaRecepcion || null,
      pdfEscaner: ot.pdfEscaner || null,
    },
    resumen: {
      totalFotos: fotos.length,
      totalDanos: danos.length,
      tieneFirmas: Boolean(ot.firma?.firmaCliente || ot.firma?.firmaRecepcion),
      tienePdf: Boolean(ot.pdfEscaner),
    },
    accesos: {
      detalle: `/dashboard/ots/${routeId}`,
      danos: `/dashboard/ots/${routeId}/danos`,
      fotos: `/dashboard/ots/${routeId}/fotos`,
      firmas: `/dashboard/ots/${routeId}/firmas`,
      cotizacion: `/dashboard/ots/${routeId}/cotizacion`,
    },
  };
}

export async function getHistorialByClienteLocal(tarjeta: string) {
  const normalizedTarjeta = normalize(tarjeta);
  const cliente = await db.clientes.where('tarjeta').equals(tarjeta).first();
  const vehiculosRows = await db.vehiculos.toArray();
  const otsRows = await db.ordenesTrabajo.toArray();

  const vehiculos = vehiculosRows
    .filter((vehiculo) => normalize(vehiculo.clienteId) === normalizedTarjeta || (vehiculo.clienteIds || []).some((id) => normalize(id) === normalizedTarjeta))
    .sort((a, b) => normalize(a.placa).localeCompare(normalize(b.placa)))
    .map(mapVehiculo);

  const ots = sortOtsDesc(
    otsRows.filter((ot) => normalize(ot.clienteTarjeta) === normalizedTarjeta).map(mapOt),
  );

  const totalCotizado = ots.reduce((sum, ot) => sum + Number(ot.totalCotizacion || 0), 0);

  return {
    cliente: cliente
      ? {
          tarjeta: cliente.tarjeta,
          nombre: cliente.nombre,
          nit: cliente.nit,
        }
      : null,
    totalOts: ots.length,
    totalCotizado,
    vehiculos,
    ots,
    resumen: `${ots.length} OTs | ${formatCurrency(totalCotizado)}`,
  };
}

export async function getHistorialByPlacaLocal(placa: string) {
  const normalizedPlaca = normalize(placa);
  const vehiculoRow = await db.vehiculos.where('placa').equals(placa.toUpperCase()).first();
  const otsRows = await db.ordenesTrabajo.toArray();

  const ots = sortOtsDesc(
    otsRows
      .filter((ot) => normalize(ot?.vehiculo?.placa) === normalizedPlaca)
      .map(mapOt),
  );

  const totalCotizado = ots.reduce((sum, ot) => sum + Number(ot.totalCotizacion || 0), 0);
  const ultimoKm = ots.length > 0 ? Number(ots[0]?.km || 0) : undefined;

  return {
    vehiculo: vehiculoRow ? mapVehiculo(vehiculoRow) : ots[0]?.vehiculo || null,
    totalOts: ots.length,
    totalCotizado,
    ultimoKm,
    ots,
    resumen: `${ots.length} OTs | ${formatCurrency(totalCotizado)}`,
  };
}
