import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from "typeorm";
import { OrdenTrabajo } from "../ots/entities/orden-trabajo.entity";
import { Vehiculo } from "../vehiculos/entities/vehiculo.entity";

@Injectable()
export class HistorialService {
  constructor(
    @InjectRepository(OrdenTrabajo)
    private otRepository: Repository<OrdenTrabajo>,
    @InjectRepository(Vehiculo)
    private vehiculoRepository: Repository<Vehiculo>,
  ) {}

  async getHistorialByCliente(clienteTarjeta: string) {
    const ots = await this.otRepository.find({
      where: { clienteTarjeta },
      relations: [
        "vehiculo",
        "vehiculo.tipoVehiculo",
        "danos",
        "danos.tipoDano",
        "fotos",
        "firma",
        "cotizaciones",
        "cotizaciones.lineas",
      ],
      order: { fechaEntrada: "DESC" },
    });

    const totalOts = ots.length;
    const totalCotizado = ots.reduce(
      (sum, ot) => sum + Number(ot.cotizaciones?.[0]?.total || 0),
      0,
    );

    const vehiculos = await this.vehiculoRepository.find({
      where: { clienteId: clienteTarjeta },
      relations: ["tipoVehiculo"],
      order: { placa: "ASC" },
    });

    return {
      clienteTarjeta,
      totalOts,
      totalCotizado,
      vehiculos,
      ots: ots.map((ot) => this.toHistorialOt(ot)),
    };
  }

  async getHistorialByPlaca(placa: string) {
    const normalizedPlaca = placa.toUpperCase();
    const vehiculo = await this.vehiculoRepository.findOne({
      where: { placa: normalizedPlaca },
      relations: ["tipoVehiculo"],
    });

    if (!vehiculo) {
      return {
        placa: normalizedPlaca,
        vehiculo: null,
        totalOts: 0,
        totalCotizado: 0,
        ots: [],
      };
    }

    const ots = await this.otRepository.find({
      where: { vehiculoId: vehiculo.id },
      relations: [
        "vehiculo",
        "vehiculo.tipoVehiculo",
        "danos",
        "danos.tipoDano",
        "fotos",
        "firma",
        "cotizaciones",
        "cotizaciones.lineas",
      ],
      order: { fechaEntrada: "DESC" },
    });

    const totalCotizado = ots.reduce(
      (sum, ot) => sum + Number(ot.cotizaciones?.[0]?.total || 0),
      0,
    );

    const lastKm = ots.length > 0 ? Number(ots[0].km || 0) : 0;
    const firstKm = ots.length > 0 ? Number(ots[ots.length - 1].km || 0) : 0;

    return {
      placa: normalizedPlaca,
      vehiculo: {
        id: vehiculo.id,
        placa: vehiculo.placa,
        marca: vehiculo.marca,
        modelo: vehiculo.modelo,
        anio: vehiculo.anio,
        motor: vehiculo.motor,
        color: vehiculo.color,
        tipoVehiculo: vehiculo.tipoVehiculo?.nombre,
        clienteId: vehiculo.clienteId,
      },
      totalOts: ots.length,
      totalCotizado,
      kmRecorridos: lastKm - firstKm,
      ultimoKm: lastKm,
      ots: ots.map((ot) => this.toHistorialOt(ot)),
    };
  }

  private toHistorialOt(ot: OrdenTrabajo) {
    const cotizacion = ot.cotizaciones?.[0];
    const fotos = ot.fotos || [];
    const danos = ot.danos || [];
    const firma = ot.firma;

    return {
      id: ot.id,
      numeroOt: ot.numeroOt,
      fechaEntrada: ot.fechaEntrada,
      fechaSalida: ot.fechaSalida,
      estado: ot.estado,
      km: ot.km,
      requerimientoCliente: ot.requerimientoCliente,
      observaciones: ot.observaciones,
      vehiculo: ot.vehiculo
        ? {
            placa: ot.vehiculo.placa,
            marca: ot.vehiculo.marca,
            modelo: ot.vehiculo.modelo,
            anio: ot.vehiculo.anio,
            color: ot.vehiculo.color,
          }
        : null,
      totalCotizacion: Number(cotizacion?.total || 0),
      cotizacion: cotizacion
        ? {
            id: cotizacion.id,
            numeroCotizacion: cotizacion.numeroCotizacion,
            estado: cotizacion.estado,
            subtotal: Number(cotizacion.subtotal || 0),
            iva: Number(cotizacion.iva || 0),
            total: Number(cotizacion.total || 0),
            lineas: (cotizacion.lineas || []).map((linea) => ({
              id: linea.id,
              plu: linea.plu,
              descripcion: linea.descripcion,
              cantidad: Number(linea.cantidad || 0),
              total: Number(linea.total || 0),
              esServicio: Boolean(linea.esServicio),
            })),
          }
        : null,
      evidencia: {
        fotos: fotos.map((foto) => ({
          id: foto.id,
          tipo: foto.tipo,
          url: foto.url,
          descripcion: foto.descripcion,
          createdAt: foto.createdAt,
        })),
        danos: danos.map((dano) => ({
          id: dano.id,
          zona: dano.zona,
          descripcion: dano.descripcion,
          posicionX: dano.posicionX,
          posicionY: dano.posicionY,
          fotoUrl: dano.fotoUrl,
          tipo: dano.tipoDano
            ? {
                id: dano.tipoDano.id,
                nombre: dano.tipoDano.nombre,
                color: dano.tipoDano.color,
              }
            : null,
        })),
        firmaCliente: firma?.firmaCliente
          ? {
              url: firma.firmaCliente,
              nombre: firma.nombreFirmaCliente,
              fecha: firma.fechaFirmaCliente,
            }
          : null,
        firmaRecepcion: firma?.firmaRecepcion
          ? {
              url: firma.firmaRecepcion,
              nombre: firma.nombreFirmaRecepcion,
              fecha: firma.fechaFirmaRecepcion,
            }
          : null,
        pdfEscaner: ot.pdfEscaner || null,
      },
      resumen: {
        totalFotos: fotos.length,
        totalDanos: danos.length,
        tieneFirmas: Boolean(firma?.firmaCliente || firma?.firmaRecepcion),
        tienePdf: Boolean(ot.pdfEscaner),
      },
      accesos: {
        detalle: `/dashboard/ots/${ot.id}`,
        danos: `/dashboard/ots/${ot.id}/danos`,
        fotos: `/dashboard/ots/${ot.id}/fotos`,
        firmas: `/dashboard/ots/${ot.id}/firmas`,
        cotizacion: `/dashboard/ots/${ot.id}/cotizacion`,
      },
    };
  }
}
