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

export function useBulkLoadCups() {
    const handleBulkLoadElectrico = async (
        clientesFiltrados: Cliente[],
        cupsElectricos: any[],
        cupsYaUtilizados: string[],
        isDatosComunes: boolean,
        datosComunes?: any,
        progress?: BulkLoadProgressControls,
    ): Promise<any[]> => {
        const newRows: any[] = [];
        const cupsUtilizadosSet = new Set(cupsYaUtilizados);

        const tareas: Array<{ cliente: Cliente; cups: any }> = [];

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

            for (const cups of cupsPorCliente) {
                if (!cupsUtilizadosSet.has(cups.codigoCups)) {
                    tareas.push({ cliente, cups });
                }
            }
        }

        if (tareas.length === 0) {
            return [];
        }

        try {
            for (let index = 0; index < tareas.length; index++) {
                const { cliente, cups } = tareas[index];
                const porcentaje = 20 + Math.round(((index + 1) / tareas.length) * 80);
                progress?.setPercent(
                    porcentaje,
                    `${cliente.RazSocCli} — ${cups.codigoCups} (${index + 1} de ${tareas.length})`,
                );

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

                const newRow = createElectricoRow(
                    cliente,
                    cups,
                    isDatosComunes,
                    datosComunes,
                );
                newRows.push(newRow);
                cupsUtilizadosSet.add(cups.codigoCups);
            }

            return newRows;
        } catch {
            progress?.fail('Error al procesar los CUPS eléctricos');
            throw new Error('bulk-load-electrico-failed');
        }
    };

    const handleBulkLoadGas = async (
        clientesFiltrados: Cliente[],
        cupsGas: any[],
        cupsYaUtilizados: string[],
        isDatosComunes: boolean,
        datosComunes?: any,
        progress?: BulkLoadProgressControls,
    ): Promise<any[]> => {
        const newRows: any[] = [];
        const cupsUtilizadosSet = new Set(cupsYaUtilizados);

        const tareas: Array<{ cliente: Cliente; cups: any }> = [];

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

            for (const cups of cupsPorCliente) {
                if (!cupsUtilizadosSet.has(cups.codigoCups)) {
                    tareas.push({ cliente, cups });
                }
            }
        }

        if (tareas.length === 0) {
            return [];
        }

        try {
            for (let index = 0; index < tareas.length; index++) {
                const { cliente, cups } = tareas[index];
                const porcentaje = 20 + Math.round(((index + 1) / tareas.length) * 80);
                progress?.setPercent(
                    porcentaje,
                    `${cliente.RazSocCli} — ${cups.codigoCups} (${index + 1} de ${tareas.length})`,
                );

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

                const newRow = createGasRow(
                    cliente,
                    cups,
                    isDatosComunes,
                    datosComunes,
                );
                newRows.push(newRow);
                cupsUtilizadosSet.add(cups.codigoCups);
            }

            return newRows;
        } catch {
            progress?.fail('Error al procesar los CUPS de gas');
            throw new Error('bulk-load-gas-failed');
        }
    };

    return { handleBulkLoadElectrico, handleBulkLoadGas };
}

function createElectricoRow(
    cliente: Cliente,
    cups: any,
    isDatosComunes: boolean,
    datosComunes?: any,
): any {
    const baseData: any = {
        ...initialFormDataElectrico,
        tempId: `electrico-temp-${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 || '',
        subtarifa: cups.subtarifa || '',
    };

    if (isDatosComunes && datosComunes) {
        return {
            ...baseData,
            comercializadora: datosComunes.comercializadora || '',
            producto: datosComunes.producto || '',
            codigoServicioProducto: datosComunes.codigoServicioProducto || '',
            productoNombre: datosComunes.productoNombre || '',
            anexo: datosComunes.anexo || '',
            anexoNombre: datosComunes.anexoNombre || '',
            subtarifa: datosComunes.subtarifa || '',
            fechaInicio: datosComunes.fechaInicio || '',
            fechaFin: datosComunes.fechaFin || '',
            tipoprecio: datosComunes.tipoprecio || '',
            corpoGo: datosComunes.corpoGo || '',
            GDO: datosComunes.GDO || '0',
            Id_Tarifa_Automatica: datosComunes.Id_Tarifa_Automatica || '',
            permanencia: datosComunes.permanencia || '0',
            cambioTitular: datosComunes.cambioTitular || '0',
            cambioPotencia: datosComunes.cambioPotencia || '0',
            ...serviciosContratoAsTableRow(datosComunes),
        };
    }

    return baseData;
}

function createGasRow(
    cliente: Cliente,
    cups: any,
    isDatosComunes: boolean,
    datosComunes?: any,
): any {
    const baseData: any = {
        ...initialFormDataGas,
        tempId: `gas-temp-${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 || '',
        subtarifa: cups.subtarifa || '',
    };

    if (isDatosComunes && datosComunes) {
        return {
            ...baseData,
            comercializadora: datosComunes.comercializadora || '',
            producto: datosComunes.producto || '',
            codigoServicioProducto: datosComunes.codigoServicioProducto || '',
            productoNombre: datosComunes.productoNombre || '',
            anexo: datosComunes.anexo || '',
            anexoNombre: datosComunes.anexoNombre || '',
            subtarifa: datosComunes.subtarifa || '',
            fechaInicio: datosComunes.fechaInicio || '',
            fechaFin: datosComunes.fechaFin || '',
            tipoprecio: datosComunes.tipoprecio || '',
            corpoGo: datosComunes.corpoGo || '',
            GDO: datosComunes.GDO || '0',
            Id_Tarifa_Automatica: datosComunes.Id_Tarifa_Automatica || '',
            permanencia: datosComunes.permanencia || '0',
            cambioTitular: datosComunes.cambioTitular || '0',
            cambioPotencia: datosComunes.cambioPotencia || '0',
            ...serviciosContratoAsTableRow(datosComunes),
        };
    }

    return baseData;
}
