import { listarGraficos } from "@/requests/CRM/Dashboard/listarDashboard";
import { listarUsuarios } from "@/requests/CRUD/Usuario/listarUsuarios";
import { useScreenContext } from "@/src/contexts/ScreenContext";
import { useAuth } from "@/src/contexts/authContext";
import React, { useEffect, useMemo, useState } from "react";
import { GraphId, graphRegistry } from "./graph-registry";
import { Plus } from "lucide-react";
interface Grafico {
  id_grafico: string;
  nome_grafico: string;
  tipo_grafico: string;
}
type DashboardProps = {
  graficosPermitidos: string;
  lojas: string;
  usuario: any;
  periodo: any;
  tipoNegocio: any;
  classificacaoNegocio: any;
  orderFromServer?: string;
};

const Dashboard: React.FC<DashboardProps> = ({
  graficosPermitidos,
  lojas,
  usuario,
  tipoNegocio,
  classificacaoNegocio,
  periodo,
  orderFromServer,
}) => {
  const { isMobile } = useScreenContext();
  const { valuesSession } = useAuth();
  const { session } = valuesSession();
  const [loadingUsuarios, setLoadingUsuarios] = useState(false);
  const [graficos, setGraficos] = useState<Grafico[]>([]);
  const [dadosCarregados, setDadosCarregados] = useState(false);
  const activeIds: GraphId[] = useMemo(() => {
    if (graficosPermitidos === "all")
      return Object.keys(graphRegistry) as GraphId[];
    if (!graficosPermitidos) return [];
    return graficosPermitidos.split("^").filter(Boolean) as GraphId[];
  }, [graficosPermitidos]);

  useEffect(() => {
    let mounted = true;

    setLoadingUsuarios(true);

    Promise.all([listarGraficos(), listarUsuarios(session.id_loja_usuario)])
      .then(([graficosRes]) => {
        if (!mounted) return;
        setGraficos(graficosRes);
        setDadosCarregados(true);
      })
      .finally(() => {
        if (!mounted) return;
        setLoadingUsuarios(false);
      });

    return () => {
      mounted = false;
    };
  }, [lojas, session.id_loja_usuario]);

  const orderedActiveIds = useMemo(() => {
    const idsSet = new Set(activeIds);
    const all = Object.values(graphRegistry).filter((g) => idsSet.has(g.id));

    if (orderFromServer) {
      const orderArr = orderFromServer
        .split(",")
        .map((s) => s.trim()) as GraphId[];
      const orderMap = new Map(orderArr.map((id, idx) => [id, idx]));
      return all
        .sort(
          (a, b) => (orderMap.get(a.id) ?? 1e9) - (orderMap.get(b.id) ?? 1e9)
        )
        .map((g) => g.id);
    }

    return all.sort((a, b) => a.defaultOrder - b.defaultOrder).map((g) => g.id);
  }, [activeIds, orderFromServer]);

  if (activeIds.length === 0) {
    return null;
  }

  if (!dadosCarregados) {
    return <div>Loading...</div>;
  }
  return (
    <div className="mt-4 space-y-6">
      <div>
        <h2 className="text-lg font-bold text-black mb-3">
          QUADROS DE INFORMAÇÕES GERENCIAIS {periodo !== "*" && "DO PERÍODO"}
        </h2>
        <div className="grid grid-cols-12 gap-4">
          {orderedActiveIds
            .filter((id) => graphRegistry[id]?.detailed || id === "15")
            .map((id) => {
              const meta = graphRegistry[id];
              if (!meta) return null;
              const graficoOrdenado = graficos.find(
                (item) => item.id_grafico == id
              );
              const Component = meta.import as React.ComponentType<any>;
              const colSpan = isMobile
                ? meta.colSpan.mobile
                : meta.colSpan.desktop;

              const props: Record<string, any> = { lojas };
              if (lojas === "*") {
                props.lojas = "";
              }
              props.usuarios = usuario;

              props.tipoNegocio = tipoNegocio;
              props.classificacaoNegocio = classificacaoNegocio;
              if (id === "16") props.status = 1;
              if (id === "1") props.status = 0;
              if (id === "20") props.status = 3;
              if (id === "21") props.status = "*";
              props.data = graficoOrdenado;
              if (typeof periodo === "object" && periodo !== null) {
                periodo = JSON.stringify(periodo);
              }
              props.periodoSelecionado = periodo;

              return (
                <div
                  key={id}
                  className={`col-span-${colSpan} relative group border-2 text-black border-strokedark/20 rounded-lg p-1 transition-colors duration-150 ${graphRegistry[id]?.detailed ? "hover:border-primary" : ""}`}
                >
                  {graphRegistry[id]?.detailed && (
                    <div
                      className="pointer-events-none absolute inset-x-0 top-0 flex justify-center
                      opacity-0 -translate-y-1 transition-opacity transition-transform duration-150 ease-out
                      group-hover:opacity-100 group-hover:translate-y-0 will-change-transform transform-gpu"
                    >
                      <div className="bg-primary/95 gap-1 text-white text-xs px-9 flex items-center rounded-b-lg text-center">
                        <Plus size={14} /> Clique para detalhar
                      </div>
                    </div>
                  )}

                  <Component {...props} />
                </div>
              );
            })}
        </div>
      </div>

      <div>
        <div className="flex flex-wrap items-center justify-between gap-3 mb-3">
          <h2 className="text-lg font-bold  text-black">
            GRÁFICOS GERENCIAIS {periodo !== "*" && "DO PERÍODO"}
          </h2>
        </div>
        <div className="grid grid-cols-12 gap-4">
          {orderedActiveIds
            .filter((id) => !graphRegistry[id]?.detailed && id !== "15")
            .map((id) => {
              const meta = graphRegistry[id];
              if (!meta) return null;
              const graficoOrdenado = graficos.find(
                (item) => item.id_grafico == id
              );
              const Component = meta.import as React.ComponentType<any>;
              const colSpan = isMobile
                ? meta.colSpan.mobile
                : meta.colSpan.desktop;

              const props: Record<string, any> = { lojas };
              if (lojas === "*") {
                props.lojas = "";
              }
              props.usuarios = usuario;
              if (id === "16") props.status = 1;
              props.data = graficoOrdenado;
              if (typeof periodo === "object" && periodo !== null) {
                periodo = JSON.stringify(periodo);
              }
              props.label = meta.label;
              props.tipoNegocio = tipoNegocio;
              props.classificacaoNegocio = classificacaoNegocio;
              props.periodoSelecionado = periodo;

              return (
                <div
                  key={id}
                  className={`col-span-${colSpan} relative group border-2 text-black border-strokedark/20 rounded-lg p-1 transition-colors duration-150`}
                >
                  <Component {...props} />
                </div>
              );
            })}
        </div>
      </div>
    </div>
  );
};

export default Dashboard;
