"use client";

import { useState, useEffect } from "react";
import axios from "axios";
import Cookies from "js-cookie";
import styles from "./pregunta3.module.scss";
import ToggleButton from "../Toggle/ToggleButton";
import { PROCESADORES_POR_EQUIPO } from "@/data/procesadores";

/* ---------- types ---------- */
type ProcessorEntry = {
  tipo: string;
  alumnos: string;
  profesores: string;
  tecnicos: string;
  investigadores: string;
  administrativos: string;
  total: string;
  isTotal?: boolean;
};

type PlatformKey =
  | "pc-desktop"
  | "apple-desktop"
  | "pc-laptop"
  | "apple-laptop"
  | "servers";

type PlatformData = Record<PlatformKey, ProcessorEntry[]>;

/* ---------- labels ---------- */
const PLATFORM_LABELS: Record<PlatformKey, string> = {
  "pc-desktop": "Computadoras de escritorio Plataforma PC",
  "apple-desktop": "Computadoras de escritorio Plataforma Apple",
  "pc-laptop": "Computadoras portátiles Plataforma PC",
  "apple-laptop": "Computadoras portátiles Plataforma Apple",
  servers: "Alto rendimiento Servidores",
};

/* ---------- mapeo uso -> campo ---------- */
const USO_TO_FIELD: Record<
  string,
  keyof Omit<ProcessorEntry, "tipo" | "total" | "isTotal">
> = {
  ALUMNO: "alumnos",
  PROFESOR: "profesores",
  "TÉCNICO ACADEMICO": "tecnicos",
  INVESTIGADOR: "investigadores",
  ADMINISTRATIVO: "administrativos",
};

/* ---------- mapa platformKey -> PROCESADORES_POR_EQUIPO keys ---------- */
/* Este mapa indica qué conjuntos de procesadores corresponden a cada PlatformKey.
   Ajusta si quieres incluir/excluir grupos. */
const PLATFORM_PROCESSOR_GROUPS: Record<PlatformKey, number[]> = {
  "pc-desktop": [1, 3], // escritorio PC + escritorio Linux (ambos comparten procesadores)
  "apple-desktop": [2],
  "pc-laptop": [4, 5],
  "apple-laptop": [6],
  servers: [10],
};

/* ---------- helpers ---------- */
function cleanName(str: string) {
  return (
    String(str)
      .normalize?.("NFKD")
      .replace?.(/\u00A0/g, " ")
      .replace?.(/\s+/g, " ")
      .trim?.() ?? String(str)
  );
}

/* Devuelve la lista "oficial" de procesadores (strings) para la plataforma */
function getOfficialProcessors(platform: PlatformKey): string[] {
  const groups = PLATFORM_PROCESSOR_GROUPS[platform] || [];
  const names: string[] = [];
  for (const g of groups) {
    const arr = PROCESADORES_POR_EQUIPO[g] || [];
    for (const p of arr) {
      names.push(p.procesador);
    }
  }
  // dedupe preserving order
  const seen = new Set<string>();
  return names.filter((n) => {
    const c = cleanName(n).toLowerCase();
    if (seen.has(c)) return false;
    seen.add(c);
    return true;
  });
}

/* ---------- transformación de datos ---------- */
function transformProcessorDataWithOfficial(
  rawArray: { procesador: string; uso: string; total: string }[],
  platform: PlatformKey
): ProcessorEntry[] {
  // 1) crear mapa cleanedName -> aggregated numbers por uso
  const mapRaw: Record<string, { [k in keyof typeof USO_TO_FIELD]?: number }> =
    {};

  for (const r of rawArray) {
    const name = cleanName(r.procesador);
    const usoKey = String(r.uso).toUpperCase();
    const field = USO_TO_FIELD[usoKey];
    if (!mapRaw[name]) {
      mapRaw[name] = {};
    }
    const prev = parseInt(r.total || "0") || 0;
    if (field) {
      mapRaw[name][field] = (mapRaw[name][field] || 0) + prev;
    }
  }

  // 2) obtener lista oficial y construir filas fijas primero
  const official = getOfficialProcessors(platform);
  const fixedRows: ProcessorEntry[] = official.map((proc) => {
    const c = cleanName(proc);
    const sums = mapRaw[c] || {};
    const alumnos = (sums["alumnos"] || 0).toString();
    const profesores = (sums["profesores"] || 0).toString();
    const tecnicos = (sums["tecnicos"] || 0).toString();
    const investigadores = (sums["investigadores"] || 0).toString();
    const administrativos = (sums["administrativos"] || 0).toString();
    const total =
      (parseInt(alumnos) || 0) +
      (parseInt(profesores) || 0) +
      (parseInt(tecnicos) || 0) +
      (parseInt(investigadores) || 0) +
      (parseInt(administrativos) || 0);
    return {
      tipo: proc,
      alumnos,
      profesores,
      tecnicos,
      investigadores,
      administrativos,
      total: total.toString(),
    };
  });

  // 3) extras: procesadores del backend que no están en official
  const officialSet = new Set(official.map((p) => cleanName(p).toLowerCase()));
  const extras = Object.keys(mapRaw)
    .filter((k) => !officialSet.has(k.toLowerCase()))
    .sort((a, b) => a.localeCompare(b, undefined, { sensitivity: "base" }))
    .map((cleaned) => {
      const sums = mapRaw[cleaned] || {};
      const alumnos = (sums["alumnos"] || 0).toString();
      const profesores = (sums["profesores"] || 0).toString();
      const tecnicos = (sums["tecnicos"] || 0).toString();
      const investigadores = (sums["investigadores"] || 0).toString();
      const administrativos = (sums["administrativos"] || 0).toString();
      const total =
        (parseInt(alumnos) || 0) +
        (parseInt(profesores) || 0) +
        (parseInt(tecnicos) || 0) +
        (parseInt(investigadores) || 0) +
        (parseInt(administrativos) || 0);
      return {
        tipo: cleaned, // mostrar cleaned name (luego puedes mostrar raw si tienes map)
        alumnos,
        profesores,
        tecnicos,
        investigadores,
        administrativos,
        total: total.toString(),
      } as ProcessorEntry;
    });

  // 4) concatenar fixedRows + extras, luego grand total
  const allRows = [...fixedRows, ...extras];

  const grandTotal: ProcessorEntry = {
    tipo: "Total",
    alumnos: allRows
      .reduce((sum, r) => sum + (parseInt(r.alumnos || "0") || 0), 0)
      .toString(),
    profesores: allRows
      .reduce((sum, r) => sum + (parseInt(r.profesores || "0") || 0), 0)
      .toString(),
    tecnicos: allRows
      .reduce((sum, r) => sum + (parseInt(r.tecnicos || "0") || 0), 0)
      .toString(),
    investigadores: allRows
      .reduce((sum, r) => sum + (parseInt(r.investigadores || "0") || 0), 0)
      .toString(),
    administrativos: allRows
      .reduce((sum, r) => sum + (parseInt(r.administrativos || "0") || 0), 0)
      .toString(),
    total: allRows
      .reduce((sum, r) => sum + (parseInt(r.total || "0") || 0), 0)
      .toString(),
    isTotal: true,
  };

  return [...allRows, grandTotal];
}

/* ---------- componente ---------- */
export default function Pregunta3_2() {
  const [activeTab, setActiveTab] = useState<PlatformKey>("pc-desktop");
  const [data, setData] = useState<PlatformData | null>(null);
  const [loading, setLoading] = useState(true);

  const cargarDatos = async (baja: boolean) => {
    setLoading(true);
    const token = Cookies.get("token");
    if (!token) {
      console.error("Token no encontrado");
      setLoading(false);
      return;
    }

    const body = baja ? ["BAJA"] : ["EN DESUSO", "EN USO"];
    const headers = { Authorization: `Bearer ${token}` };

    axios
      .post(
        `${process.env.NEXT_PUBLIC_API_URL}/equipos/reporte/tipoEquipos_procesador`,
        body,
        { headers }
      )
      .then((res) => {
        const json = res.data; // array con 5 arrays

        const formatted: PlatformData = {
          "pc-desktop": transformProcessorDataWithOfficial(
            json[0] || [],
            "pc-desktop"
          ),
          "apple-desktop": transformProcessorDataWithOfficial(
            json[1] || [],
            "apple-desktop"
          ),
          "pc-laptop": transformProcessorDataWithOfficial(
            json[2] || [],
            "pc-laptop"
          ),
          "apple-laptop": transformProcessorDataWithOfficial(
            json[3] || [],
            "apple-laptop"
          ),
          servers: transformProcessorDataWithOfficial(json[4] || [], "servers"),
        };

        setData(formatted);
      })
      .catch((err) => {
        console.error("Error cargando datos de procesadores", err);
        // en error, dejamos listas vacías pero con rows oficiales (0)
        const empty: PlatformData = {
          "pc-desktop": transformProcessorDataWithOfficial([], "pc-desktop"),
          "apple-desktop": transformProcessorDataWithOfficial(
            [],
            "apple-desktop"
          ),
          "pc-laptop": transformProcessorDataWithOfficial([], "pc-laptop"),
          "apple-laptop": transformProcessorDataWithOfficial(
            [],
            "apple-laptop"
          ),
          servers: transformProcessorDataWithOfficial([], "servers"),
        };
        setData(empty);
      })
      .finally(() => setLoading(false));
  };

  useEffect(() => {
    cargarDatos(false);
  }, []);

  const currentData = data?.[activeTab] ?? [];

  const isInvalidProcessor = (tipo: string, platform: PlatformKey) => {
    if (tipo === "Total") return false;
    const official = getOfficialProcessors(platform).map((p) =>
      cleanName(p).toLowerCase()
    );
    return !official.includes(cleanName(tipo).toLowerCase());
  };

  return (
    <div className={styles.container_P3}>
      <div className={styles["contenedor-censo_P3"]}>
        Censo de equipos de cómputo - Plataforma y tipo procesador
      </div>

      <div className={styles["pregunta-cuadro_P3"]}>
        Cantidad de población beneficiada por plataforma y tipo de procesador.
        <ToggleButton
          onChange={(estado) => {
            cargarDatos(estado);
          }}
        />
      </div>

      <div className={styles.scanView_P3}>
        <div className={styles.mainContent_P3}>
          <div className={styles.tabs_P3}>
            {Object.entries(PLATFORM_LABELS).map(([key, label]) => (
              <button
                key={key}
                className={`${styles.tab_P3} ${
                  activeTab === key ? styles.active_P3 : ""
                }`}
                onClick={() => setActiveTab(key as PlatformKey)}
                aria-selected={activeTab === key}
              >
                {label}
              </button>
            ))}
          </div>

          <div className={styles.content_P3}>
            <div className={styles.tableWrapper_P3}>
              <table className={styles.table_P3}>
                <thead>
                  <tr>
                    <th rowSpan={2} className={styles.headerProcesador}>
                      {activeTab.includes("apple")
                        ? "Plataforma Apple"
                        : "Plataforma PC"}{" "}
                      <br />
                      Tipo de procesador
                    </th>
                    <th colSpan={5} className={styles.headerPoblacion}>
                      Población Beneficiada
                    </th>
                    <th rowSpan={2} className={styles.headerTotal}>
                      Total
                    </th>
                  </tr>
                  <tr>
                    <th className={styles.subHeader}>Alumnos</th>
                    <th className={styles.subHeader}>Profesores</th>
                    <th className={styles.subHeader}>Técnicos Académicos</th>
                    <th className={styles.subHeader}>Investigadores</th>
                    <th className={styles.subHeader}>Administrativos</th>
                  </tr>
                </thead>
                <tbody>
                  {currentData.map((item, idx) => {
                    const invalid = isInvalidProcessor(item.tipo, activeTab);
                    const rowClass = item.isTotal
                      ? styles.totalRow_P3
                      : invalid
                      ? styles.invalidRow_P3
                      : styles.dataRow_P3;

                    return (
                      <tr key={idx} className={rowClass}>
                        <td className={styles.processor_P3}>{item.tipo}</td>

                        <td>
                          {loading ? (
                            <div className="skeleton" />
                          ) : (
                            <input
                              type="text"
                              value={item.alumnos}
                              readOnly
                              className={styles.inputBox_P3}
                            />
                          )}
                        </td>

                        <td>
                          {loading ? (
                            <div className="skeleton" />
                          ) : (
                            <input
                              type="text"
                              value={item.profesores}
                              readOnly
                              className={styles.inputBox_P3}
                            />
                          )}
                        </td>

                        <td>
                          {loading ? (
                            <div className="skeleton" />
                          ) : (
                            <input
                              type="text"
                              value={item.tecnicos}
                              readOnly
                              className={styles.inputBox_P3}
                            />
                          )}
                        </td>

                        <td>
                          {loading ? (
                            <div className="skeleton" />
                          ) : (
                            <input
                              type="text"
                              value={item.investigadores}
                              readOnly
                              className={styles.inputBox_P3}
                            />
                          )}
                        </td>

                        <td>
                          {loading ? (
                            <div className="skeleton" />
                          ) : (
                            <input
                              type="text"
                              value={item.administrativos}
                              readOnly
                              className={styles.inputBox_P3}
                            />
                          )}
                        </td>

                        <td className={styles.totalCell_P3}>
                          {loading ? (
                            <div className="skeleton" />
                          ) : (
                            item.total
                          )}
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>

            {currentData.length === 0 && (
              <div className={styles.emptyState_P3}>
                No hay datos disponibles para esta plataforma.
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}
