"""
Validaciones comunes de fila para import CSV de tipos de cambio.
Paridad Clarion: desfase (Col C vacía), obligatorios (Col A Fecha, Col B Tipo de Cambio),
validación fecha (longitud, día acorde al mes, mes ≤ 12; sin límite de año).
"""
from typing import Dict, Any, Optional, List

from ...common.cell_value import cell_to_str
from ..common.common_validators import (
    check_required_value_positive,
    check_optional_max_length,
    validate_fecha_clarion,
    CURRENCY_MAX,
)


MSG_DESFASE = "Error: Existe un desfase en esta línea."
MSG_DESFASE_SOLUCION = "Revisar esta línea del archivo CSV y verificar cada campo este en la posicion correcta."

MSG_OBLIGATORIOS = "Existen campos vacios que son obligatorios, es la (Col.A) Fecha , (Col.B) Tipo de Cambio."
MSG_OBLIGATORIOS_SOLUCION = "Revisar la línea del archivo y capturar los campos con la información correcta."


def validate_row_desfase(raw_row: Dict[str, Any], line_num: int) -> Optional[Dict[str, Any]]:
    """
    Si la fila tiene 3 o más columnas y la 3ª tiene valor, error de desfase (Clarion ColumnaC <> '').
    """
    values_ordered = list(raw_row.values()) if raw_row else []
    if len(values_ordered) >= 3:
        cell = cell_to_str(values_ordered[2])
        if cell.strip():
            return {
                "line": line_num,
                "col": "",
                "msg": f"{MSG_DESFASE} {MSG_DESFASE_SOLUCION}",
                "warning": True,
            }
    return None


def validate_row_required_exchange_rate(row: Dict[str, Any], line_num: int) -> Optional[Dict[str, Any]]:
    """FECHA y VALOR obligatorios con mensaje Clarion."""
    fecha = (row.get("FECHA") or "").strip()
    valor = (row.get("VALOR") or "").strip()
    if not fecha or not valor:
        return {
            "line": line_num,
            "col": "FECHA" if not fecha else "VALOR",
            "msg": f"{MSG_OBLIGATORIOS} {MSG_OBLIGATORIOS_SOLUCION}",
        }
    return None


def validate_row_fecha_clarion(
    row: Dict[str, Any], line_num: int, date_format_preference: Optional[str] = None
) -> Optional[Dict[str, Any]]:
    """Longitud ≤ 10 y fecha válida (día acorde al mes, mes ≤ 12; sin límite de año)."""
    raw_fecha = (row.get("FECHA") or "").strip()
    if not raw_fecha:
        return None
    return validate_fecha_clarion(raw_fecha, line_num, date_format_preference)


def validate_row_exchange_rate(
    row: Dict[str, Any],
    line_num: int,
    raw_row: Optional[Dict[str, Any]] = None,
    date_format_preference: Optional[str] = None,
) -> List[Dict[str, Any]]:
    """
    Valida una fila de CSV de tipos de cambio.
    Orden: desfase (si raw_row) → obligatorios → fecha Clarion → VALOR > 0 → MONEDA opc (max 7).
    date_format_preference: valor del parámetro global (ej. dd/mm/yyyy, mm/dd/yyyy, yyyy-mm-dd).
    """
    errors: List[Dict[str, Any]] = []

    if raw_row is not None:
        err = validate_row_desfase(raw_row, line_num)
        if err:
            errors.append(err)

    err = validate_row_required_exchange_rate(row, line_num)
    if err:
        errors.append(err)

    err = validate_row_fecha_clarion(row, line_num, date_format_preference)
    if err:
        errors.append(err)

    err = check_required_value_positive(row, line_num)
    if err:
        errors.append(err)

    err = check_optional_max_length(row, "MONEDA_LOCAL", CURRENCY_MAX, line_num)
    if err:
        errors.append(err)

    err = check_optional_max_length(row, "MONEDA_EXTRANJERA", CURRENCY_MAX, line_num)
    if err:
        errors.append(err)

    return errors
