import { FormDataElectrico, FormDataGas, Cliente } from '../../Interfaces/Interfaces';
import { initialFormDataElectrico, initialFormDataGas } from '../../Interfaces/constants';
import { serviciosContratoAsTableRow } from '../../ComponentesComunes/serviciosContratoConfig';
import type { BulkLoadProgressControls } from '../../Shared/bulkLoadProgress';

interface UseBulkLoadCupsProps {
    dataElectrico: FormDataElectrico[];
    dataGas: FormDataGas[];
    setData: (key: any, value: any) => void;
    cupsElectricos: any[];
    cupsGas: any[];
    selectedCliente: Cliente[];
    isDatosComunes: boolean;
    progressElectrico?: BulkLoadProgressControls;
    progressGas?: BulkLoadProgressControls;
}

export const useBulkLoadCups = ({
    dataElectrico,
    dataGas,
    setData,
    cupsElectricos,
    cupsGas,
    selectedCliente,
    isDatosComunes,
    progressElectrico,
    progressGas,
}: UseBulkLoadCupsProps) => {
    const handleBulkLoadElectrico = async () => {
        if (!selectedCliente || selectedCliente.length === 0) {
            return;
        }

        const cliente = selectedCliente[0];

        const cupsPorCliente = cupsElectricos.filter(
            (cup: any) => cup.CodCli === cliente.CodCli,
        );

        const cupsYaUtilizados = new Set(dataElectrico.map((row) => row.cups_electrico));

        const cupsDisponibles = cupsPorCliente.filter(
            (cup: any) => !cupsYaUtilizados.has(cup.codigoCups),
        );

        if (cupsDisponibles.length === 0) {
            return;
        }

        const newRows: FormDataElectrico[] = [];

        let datosComunesRef = null;
        if (isDatosComunes && dataElectrico.length > 0) {
            const firstRow = dataElectrico[0];
            datosComunesRef = {
                comercializadora: firstRow.comercializadora,
                producto: firstRow.producto,
                codigoServicioProducto: firstRow.codigoServicioProducto,
                productoNombre: firstRow.productoNombre,
                anexo: firstRow.anexo,
                anexoNombre: firstRow.anexoNombre,
                fechaInicio: firstRow.fechaInicio,
                fechaFin: firstRow.fechaFin,
                tipoprecio: firstRow.tipoprecio,
                corpoGo: firstRow.corpoGo,
                GDO: firstRow.GDO,
                Id_Tarifa_Automatica: firstRow.Id_Tarifa_Automatica,
                permanencia: firstRow.permanencia,
                cambioTitular: firstRow.cambioTitular,
                cambioPotencia: firstRow.cambioPotencia,
                ...serviciosContratoAsTableRow(firstRow),
            };
        }

        progressElectrico?.start('Cargando CUPS eléctricos...');

        try {
            const total = cupsDisponibles.length;

            for (let index = 0; index < cupsDisponibles.length; index++) {
                const cups = cupsDisponibles[index];
                progressElectrico?.update(
                    index + 1,
                    total,
                    `${cliente.RazSocCli} — ${cups.codigoCups} (${index + 1} de ${total})`,
                );

                await new Promise((resolve) => setTimeout(resolve, 0));

                const newRow = createElectricoRow(
                    cliente,
                    cups,
                    isDatosComunes,
                    datosComunesRef,
                );
                newRows.push(newRow);
            }

            setData('electrico', [...dataElectrico, ...newRows]);
            progressElectrico?.complete(`Se cargaron ${newRows.length} CUPS eléctricos`);
        } catch {
            progressElectrico?.fail('Error al cargar los CUPS eléctricos');
        }
    };

    const handleBulkLoadGas = async () => {
        if (!selectedCliente || selectedCliente.length === 0) {
            return;
        }

        const cliente = selectedCliente[0];

        const cupsPorCliente = cupsGas.filter(
            (cup: any) => cup.CodCli === cliente.CodCli,
        );

        const cupsYaUtilizados = new Set(dataGas.map((row) => row.cupsGas));

        const cupsDisponibles = cupsPorCliente.filter(
            (cup: any) => !cupsYaUtilizados.has(cup.codigoCups),
        );

        if (cupsDisponibles.length === 0) {
            return;
        }

        const newRows: FormDataGas[] = [];

        let datosComunesRef = null;
        if (isDatosComunes && dataGas.length > 0) {
            const firstRow = dataGas[0];
            datosComunesRef = {
                comercializadora: firstRow.comercializadora,
                producto: firstRow.producto,
                codigoServicioProducto: firstRow.codigoServicioProducto,
                productoNombre: firstRow.productoNombre,
                anexo: firstRow.anexo,
                anexoNombre: firstRow.anexoNombre,
                fechaInicio: firstRow.fechaInicio,
                fechaFin: firstRow.fechaFin,
                tipoprecio: firstRow.tipoprecio,
                corpoGo: firstRow.corpoGo,
                GDO: firstRow.GDO,
                Id_Tarifa_Automatica: firstRow.Id_Tarifa_Automatica,
                ...serviciosContratoAsTableRow(firstRow),
            };
        }

        progressGas?.start('Cargando CUPS de gas...');

        try {
            const total = cupsDisponibles.length;

            for (let index = 0; index < cupsDisponibles.length; index++) {
                const cups = cupsDisponibles[index];
                progressGas?.update(
                    index + 1,
                    total,
                    `${cliente.RazSocCli} — ${cups.codigoCups} (${index + 1} de ${total})`,
                );

                await new Promise((resolve) => setTimeout(resolve, 0));

                const newRow = createGasRow(
                    cliente,
                    cups,
                    isDatosComunes,
                    datosComunesRef,
                );
                newRows.push(newRow);
            }

            setData('gas', [...dataGas, ...newRows]);
            progressGas?.complete(`Se cargaron ${newRows.length} CUPS de gas`);
        } catch {
            progressGas?.fail('Error al cargar los CUPS de gas');
        }
    };

    return {
        handleBulkLoadElectrico,
        handleBulkLoadGas,
    };
};

function createElectricoRow(
    cliente: Cliente,
    cups: any,
    isDatosComunes: boolean,
    datosComunes: any,
): FormDataElectrico {
    const baseData: any = {
        ...initialFormDataElectrico,
        tempId: `electrico-bulk-${Date.now()}-${Math.floor(Math.random() * 1000000)}`,
        clienteId: cliente.CodCli,
        documento_fiscal: cliente.NumCifCli,
        razon_social: cliente.RazSocCli,
        cupsId: cups.cupsId || '',
        cups_electrico: cups.codigoCups || '',
        codigoCups: cups.codigoCups || '',
        direccion: cups.direccion || '',
        nombreTarifa: cups.nombreTarifa || '',
        consumo_kw: cups.ConAnuCup || '',
        tarifa: cups.tarifa || '',
        CodPunSum: cups.CodPunSum || '',
        EscPunSum: cups.EscPunSum || '',
        PlaPunSum: cups.PlaPunSum || '',
        PuePunSum: cups.PuePunSum || '',
        BloPunSum: cups.BloPunSum || '',
        CodLoc: cups.CodLoc || '',
        CPLocSoc: cups.CPLocSoc || '',
        codigo_postal: cups.CPLocSoc || '',
        potencia1: cups.PotConP1 || '',
        potencia2: cups.PotConP2 || '',
        potencia3: cups.PotConP3 || '',
        potencia4: cups.PotConP4 || '',
        potencia5: cups.PotConP5 || '',
        potencia6: cups.PotConP6 || '',
        Id_Tarifa_Automatica: cups.Id_Tarifa_Automatica || '',
    };

    if (isDatosComunes && datosComunes) {
        return {
            ...baseData,
            ...datosComunes,
        };
    }

    return baseData;
}

function createGasRow(
    cliente: Cliente,
    cups: any,
    isDatosComunes: boolean,
    datosComunes: any,
): FormDataGas {
    const baseData: any = {
        ...initialFormDataGas,
        tempId: `gas-bulk-${Date.now()}-${Math.floor(Math.random() * 1000000)}`,
        clienteId: cliente.CodCli,
        documento_fiscal: cliente.NumCifCli,
        razon_social: cliente.RazSocCli,
        cupsGasId: cups.cupsGasId || '',
        cupsGas: cups.codigoCups || '',
        codigoCups: cups.codigoCups || '',
        direccionGas: cups.direccion || '',
        nombreTarifa: cups.nombreTarifa || '',
        consumoGas: cups.ConAnuCup || '',
        tarifaGas: cups.tarifa || '',
        CodPunSum: cups.CodPunSum || '',
        EscPunSum: cups.EscPunSum || '',
        PlaPunSum: cups.PlaPunSum || '',
        PuePunSum: cups.PuePunSum || '',
        BloPunSum: cups.BloPunSum || '',
        CodLoc: cups.CodLoc || '',
        CPLocSoc: cups.CPLocSoc || '',
        codigo_postal: cups.CPLocSoc || '',
        DerAccKW: cups.DerAccKW || '',
        caudal_diario: cups.DerAccKW || '',
        Id_Tarifa_Automatica: cups.Id_Tarifa_Automatica || '',
    };

    if (isDatosComunes && datosComunes) {
        return {
            ...baseData,
            ...datosComunes,
        };
    }

    return baseData;
}
