import {
    SUMINISTRO_ELECTRICO_SECTIONS,
    SuministroFieldDefinition,
    SuministroFieldFormat,
} from '../config/suministroElectricoFields';
import { formatSipsNumber, toNumber } from '../types';

export const EMPTY_DISPLAY = '—';

export interface SuministroFieldViewModel {
    id: string;
    label: string;
    displayValue: string;
    highlight?: boolean;
}

export interface SuministroSectionViewModel {
    id: string;
    title: string;
    fields: SuministroFieldViewModel[];
}

function isEmptyValue(value: unknown): boolean {
    if (value === null || value === undefined) {
        return true;
    }

    if (typeof value === 'string') {
        return value.trim() === '';
    }

    return false;
}

export function resolveSuministroValue(
    suministro: Record<string, unknown>,
    field: SuministroFieldDefinition,
): unknown {
    for (const key of field.keys) {
        const value = suministro[key];

        if (!isEmptyValue(value)) {
            return value;
        }
    }

    return null;
}

function formatDateValue(value: unknown): string {
    if (isEmptyValue(value)) {
        return EMPTY_DISPLAY;
    }

    const raw = String(value).trim();
    const isoMatch = raw.match(/^(\d{4})-(\d{2})-(\d{2})/);

    if (isoMatch) {
        return `${isoMatch[3]}/${isoMatch[2]}/${isoMatch[1]}`;
    }

    return raw;
}

export function formatSuministroValue(value: unknown, format: SuministroFieldFormat): string {
    if (isEmptyValue(value)) {
        return EMPTY_DISPLAY;
    }

    switch (format) {
        case 'power':
            return formatSipsNumber(value, 2);
        case 'number':
            return formatSipsNumber(value, 0);
        case 'currency': {
            const amount = toNumber(value as string | number);
            return `${formatSipsNumber(amount, 2)} €`;
        }
        case 'date':
            return formatDateValue(value);
        case 'text':
        default:
            return String(value).trim();
    }
}

export function mapFieldToViewModel(
    suministro: Record<string, unknown>,
    field: SuministroFieldDefinition,
): SuministroFieldViewModel {
    const raw = resolveSuministroValue(suministro, field);

    return {
        id: field.id,
        label: field.label,
        displayValue: formatSuministroValue(raw, field.format),
        highlight: field.highlight,
    };
}

export function mapSuministroToViewModel(
    suministro: Record<string, unknown>,
): SuministroSectionViewModel[] {
    return SUMINISTRO_ELECTRICO_SECTIONS.map((section) => ({
        id: section.id,
        title: section.title,
        fields: section.fields.map((field) => mapFieldToViewModel(suministro, field)),
    }));
}

/** Fixture verificado contra API ADX — CUPS ES0022000005446022YT */
export const VALIDATION_FIXTURE_ES0022: Record<string, unknown> = {
    CUPS: 'ES0022000005446022YT',
    Cod_Dist: '0022',
    Distribuidora: 'UNION FENOSA DISTRIBUCION, S.A.',
    Tarifa: '2.0TD',
    Des_Tarifa: '',
    Tension: '1X230',
    Direccion_Suministro: '',
    Cod_Postal_Suministro: '19002',
    Localidad_Suministro: 'Guadalajara',
    Provincia_Suministro: 'Guadalajara',
    Indicativo_ICP: '0',
    Propiedad_ICP: 'Otros',
    telegestion: 'Telegestión operativa con Curva de Carga Horaria',
    Perfil_Consumo: 'P2.0TD',
    Tipo_PM: 'Punto de medida tipo 5',
    Propiedad_Equipo_Medida: 'Distribuidor',
    last_comer_known: '',
    Tipo_Titular: 'NIF',
    Persona: 'NI',
    Primera_vivienda: 'SI',
    Cortes: 0,
    Impago: 0,
    Pot_Cont_P1: 5.75,
    Pot_Cont_P2: 5.75,
    Pot_Cont_P3: 0,
    Pot_Cont_P4: 0,
    Pot_Cont_P5: 0,
    Pot_Cont_P6: 0,
    Pot_Max_BIE: 5.75,
    Pot_Max_Puesta: 0,
    Der_Acceso_Llano: 5.75,
    importeDepositoGarantiaEuros: '12',
};

export function countMatchingValidationFields(viewModel: SuministroSectionViewModel[]): number {
    const expectations: Record<string, string> = {
        'sips-cups': 'ES0022000005446022YT',
        'sips-cod-dist': '0022',
        'sips-distribuidora': 'UNION FENOSA DISTRIBUCION, S.A.',
        'sips-tarifa': '2.0TD',
        'sips-tension': '1X230',
        'sips-cp-suministro': '19002',
        'sips-localidad-suministro': 'Guadalajara',
        'sips-provincia-suministro': 'Guadalajara',
        'sips-indicativo-icp': '0',
        'sips-propiedad-icp': 'Otros',
        'sips-perfil-consumo': 'P2.0TD',
        'sips-tipo-pm': 'Punto de medida tipo 5',
        'sips-propiedad-em': 'Distribuidor',
        'sips-tipo-titular': 'NIF',
        'sips-primera-vivienda': 'SI',
        'sips-cortes': '0',
        'sips-impago': '0',
        'sips-pot-p1': '5,75',
        'sips-pot-p2': '5,75',
        'sips-pot-max-bie': '5,75',
        'sips-der-acceso': '5,75',
    };

    const fieldsById = new Map(
        viewModel.flatMap((section) => section.fields.map((field) => [field.id, field.displayValue] as const)),
    );

    return Object.entries(expectations).filter(([id, expected]) => fieldsById.get(id) === expected).length;
}
