import LoaderSun from "@/components/common/Loader/LoaderSun";
import InputSelectComponent from "@/components/Forms/InputSelect";
import PeriodoFiltro from "../periodoFiltro";
import Grafico, { TiposGrafico } from "@/pages/CXESCRM011/Grafico";
import { useAuth } from "@/src/contexts/authContext";
import React, { useEffect, useState } from "react";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";

const periodsPadrao = [
  { value: "todos", label: "Todos" },
  { value: "dia", label: "Dia" },
  { value: "mes", label: "Mês" },
  { value: "ano", label: "Ano" },
];
interface GraficoDinamicoProps {
  nomeGrafico: string;
  buscar: (params: {
    usuario: string;
    periodoSelecionado: string;
    lojas: string;
    tipoNegocio: any;
    classificacaoNegocio?: any;
  }) => Promise<any[]>;
  usuarios: any;
  lojas: string;
  tipoNegocio: any;
  classificacaoNegocio?: any;
  periodoSelecionado?: any;
  tiposGrafico?: string[]; // ["Pizza", "Barra", "Linha"]
  chaveLabel: string;
  chavesSeries: { nome: string; campo: string }[]; // Ex: Resolvidos, N resolvidos
  tooltipCustom?: (item: any, label: string) => string;
  serieTotalQtde?: string;
}
const tiposPadrao = [
  { value: "Pizza", label: "Pizza" }, // Pie
  { value: "Barra", label: "Barra" }, // Bar
  { value: "Coluna", label: "Coluna" }, // Column (vertical bar)
  { value: "Linha", label: "Linha" }, // Line
  { value: "Area", label: "Área" }, // Area
];

const GraficoDinamico: React.FC<GraficoDinamicoProps> = ({
  nomeGrafico,
  buscar,
  usuarios,
  lojas,
  periodoSelecionado,
  tiposGrafico = ["Pizza", "Barra", "Linha"],
  chaveLabel,
  chavesSeries,
  tipoNegocio,
  classificacaoNegocio,
  tooltipCustom,
  serieTotalQtde,
}) => {
  const { valuesSession } = useAuth();
  const { session } = valuesSession();
  const [tipo, setTipo] = useState<any>(tiposGrafico[0] as TiposGrafico);
  const [loading, setLoading] = useState(false);
  const [dados, setDados] = useState<any[]>([]);

  useEffect(() => {
    setLoading(true);
    buscar({
      usuario: usuarios,
      periodoSelecionado: periodoSelecionado,
      lojas,
      tipoNegocio,
      classificacaoNegocio,
    })
      .then((result) => {
        setDados(result || []);
      })
      .finally(() => setLoading(false));
  }, [lojas, usuarios, tipoNegocio, classificacaoNegocio, periodoSelecionado]);
  function fmtMoeda(v: any, mil = false) {
    const num = Number(v) || 0;
    return `R$ ${num.toLocaleString("pt-BR", { minimumFractionDigits: 2 })}${mil ? " mil" : ""}`;
  }
  // GraficoDinamico.tsx — versão com painel de totais customizado

  // 1. Adicione esta função helper dentro do componente:
  function calcularTotaisPropostas(dados: any[]) {
    const somar = (campo: string) =>
      dados.reduce((acc, item) => acc + (Number(item[campo]) || 0), 0);

    const series = chavesSeries.map((s) => s.nome.toLowerCase());
    const hasPropostas =
      series.includes("geradas") &&
      series.includes("aprovadas") &&
      series.includes("canceladas");
    console.log()
    if (!hasPropostas) return null;

    return {
      geradas: somar("propostas_geradas"),
      aprovadas: somar("propostas_aprovadas"),
      canceladas: somar("propostas_canceladas"),
      totais: somar("propostas_geradas") + somar("propostas_aprovadas") + somar("propostas_canceladas"),
      valorGeradas: somar("valores_geradas"),
      valorAprovadas: somar("valores_aprovadas"),
      valorCanceladas: somar("valores_canceladas"),
      valorTotais: somar("valores_geradas") + somar("valores_aprovadas") + somar("valores_canceladas")
    };
  }

  // 2. No JSX do return, adicione antes do <Grafico />:


  function splitSeriesByTipo(series: any[]) {
    const valorIdx: number[] = [];
    const qtdIdx: number[] = [];
    series.forEach((s, i) => {
      const isValor = String(s.name).toLowerCase().includes("valor");
      if (isValor) valorIdx.push(i);
      else qtdIdx.push(i);
    });
    return { valorIdx, qtdIdx };
  }

  function montarYAxes(series: any[]) {
    const { valorIdx, qtdIdx } = splitSeriesByTipo(series);
    const yaxes: any[] = [];

    qtdIdx.forEach((idx, j) => {
      yaxes.push({
        seriesName: series[idx].name,
        show: j === 0,
        title: j === 0 ? { text: "Quantidade" } : undefined,
        decimalsInFloat: 0,
        labels: { formatter: (v: number) => `${Math.round(Number(v) || 0)}` },
      });
    });

    valorIdx.forEach((idx, j) => {
      yaxes.push({
        seriesName: series[idx].name,
        opposite: true,
        show: j === 0,
        title: j === 0 ? { text: "Valor (R$)" } : undefined,
        labels: {
          formatter: (v: number) =>
            `R$ ${Number(v).toLocaleString("pt-BR", { minimumFractionDigits: 2 })}`,
        },
      });
    });

    return { yaxes, valorIdx, qtdIdx };
  }

  function formatarCategoria(raw: any) {
    if (typeof raw === "string" && /^\d{4}-\d{2}-\d{2}$/.test(raw)) {
      const [y, m, d] = raw.split("-");
      return `${d}/${m}/${y}`;
    }
    if (typeof raw === "string" && /^\d{4}-\d{2}$/.test(raw)) {
      const [ano, mes] = raw.split("-");
      const nomes = [
        "Jan",
        "Fev",
        "Mar",
        "Abr",
        "Mai",
        "Jun",
        "Jul",
        "Ago",
        "Set",
        "Out",
        "Nov",
        "Dez",
      ];
      return `${nomes[parseInt(mes, 10) - 1]}/${ano.slice(-2)}`;
    }
    return raw;
  }

  function formatarArea(dados: any) {
    const categories = dados.map((item: any) => item[chaveLabel]);
    const series = chavesSeries.map((serie) => ({
      name: serie.nome,
      data: dados.map((item: any) => Number(item[serie.campo])),
    }));
    return {
      options: {
        chart: { type: "area", zoom: { enabled: false } },
        xaxis: { categories },
        dataLabels: { enabled: false },
        stroke: { curve: "smooth" },
        tooltip: { shared: true, intersect: false },
        legend: {
          show: true,
          // Exemplo de legenda custom:
          formatter: function (seriesName: any, opts: any) {
            const valor = opts.w.globals.series[opts.seriesIndex];
            return `${seriesName}: ${valor}`;
          },
        },
      },
      series,
    };
  }

  function formatarPizza(dados: any) {
    if (!dados.length)
      return { options: { chart: { type: "pie" }, labels: [] }, series: [] };

    const labels = dados.map((item: any) => item[chaveLabel]);
    const seriePrincipal = chavesSeries[0];
    const series = dados.map((item: any) => Number(item[seriePrincipal.campo]));

    const total = serieTotalQtde
      ? dados.reduce(
        (a: number, item: any) => a + (Number(item[serieTotalQtde]) || 0),
        0,
      )
      : series.reduce(
        (a: number, b: number) => a + (Number(b) || 0),
        0,
      );
    const isValor = String(seriePrincipal?.nome || "")
      .toLowerCase()
      .includes("valor");
    const isMil = String(seriePrincipal?.nome || "")
      .toLowerCase()
      .includes("mil");
    const totalFmt = isValor ? fmtMoeda(total, isMil) : `${total}`;

    return {
      options: {
        chart: { type: "pie" },
        labels,
        subtitle: {
          text: `Total: ${totalFmt}`,
          align: "right",
          offsetY: 6,
          style: { fontWeight: 600 },
        },
        dataLabels: {
          enabled: true,
          formatter: function (val: number) {
            return val.toFixed(1) + "%";
          },
        },
        legend: {
          show: true,
          formatter: function (seriesName: any, opts: any) {
            const valor = opts.w.globals.series[opts.seriesIndex];
            return `${seriesName}: ${valor}`;
          },
        },
        tooltip: {
          custom: tooltipCustom
            ? function ({ seriesIndex, w }: any) {
              const idx = seriesIndex;
              const item = dados[idx];
              if (!item) return undefined;
              const label =
                (w &&
                  w.globals &&
                  w.globals.labels &&
                  w.globals.labels[idx]) ??
                item[chaveLabel];
              return tooltipCustom(item, label);
            }
            : undefined,
        },
      },
      series,
    };
  }

  function formatarBarra(dados: any) {
    const categories = dados.map((item: any) => {
      const raw = item[chaveLabel];
      if (typeof raw === "string" && /^\d{4}-\d{2}-\d{2}$/.test(raw)) {
        const [y, m, d] = raw.split("-");
        return `${d}/${m}/${y}`;
      }
      if (typeof raw === "string" && /^\d{4}-\d{2}$/.test(raw)) {
        const [ano, mes] = raw.split("-");
        const nomes = [
          "Jan",
          "Fev",
          "Mar",
          "Abr",
          "Mai",
          "Jun",
          "Jul",
          "Ago",
          "Set",
          "Out",
          "Nov",
          "Dez",
        ];
        return `${nomes[parseInt(mes, 10) - 1]}/${ano.slice(-2)}`;
      }
      return raw;
    });

    const series = chavesSeries.map((serie) => ({
      name: serie.nome,
      data: dados.map((item: any) => Number(item[serie.campo])),
    }));

    // Totais
    const totalsBySeries = series.map((s) =>
      (s.data || []).reduce((a: number, b: number) => a + (Number(b) || 0), 0)
    );
    const totalValor = series.reduce((acc, s, i) => {
      const isValor = String(s.name).toLowerCase().includes("valor");
      return acc + (isValor ? totalsBySeries[i] : 0);
    }, 0);
    const totalQtd = serieTotalQtde
      ? dados.reduce(
        (a: number, item: any) => a + (Number(item[serieTotalQtde]) || 0),
        0,
      )
      : series.reduce((acc, s, i) => {
        const isValor = String(s.name).toLowerCase().includes("valor");
        return acc + (!isValor ? totalsBySeries[i] : 0);
      }, 0);

    let subtitleText = "";
    if (series.length === 1) {
      const isValor = String(series[0].name).toLowerCase().includes("valor");
      const isMil = String(series[0].name).toLowerCase().includes("mil");
      subtitleText = `Total: ${isValor ? fmtMoeda(totalsBySeries[0], isMil) : totalsBySeries[0]}`;
    } else {
      const hasValor = totalValor !== 0;
      const hasQtd = totalQtd !== 0;
      if (hasValor && hasQtd) {
        subtitleText = `Total Quantidade: ${totalQtd} | Total Valor: ${fmtMoeda(totalValor)}`;
      } else if (hasValor) {
        subtitleText = `Total: ${fmtMoeda(totalValor)}`;
      } else {
        subtitleText = `Total: ${totalQtd}`;
      }
    }

    return {
      options: {
        chart: {
          type: "bar",
          stacked: series.length > 1,
          toolbar: { show: false },
        },

        xaxis: { categories },
        subtitle: {
          text: subtitleText,
          align: "right",
          offsetY: 6,
          style: { fontWeight: 600 },
        },
        plotOptions: {
          bar: {
            horizontal: false,
          },
        },
        dataLabels: {
          enabled: true,
          formatter: function (val: any, opts: any) {
            const seriesName =
              opts?.w?.config?.series?.[opts.seriesIndex]?.name || "";
            const cat =
              opts?.w?.config?.xaxis?.categories?.[opts.dataPointIndex];
            if (seriesName.toLowerCase().includes("valor")) {
              return `${cat}: ${val.toLocaleString("pt-BR", { style: "currency", currency: "BRL" })}`;
            }
            return `${cat}: ${val}`;
          },
        },
        tooltip: {
          y: {
            formatter: function (val: any, opts: any) {
              const seriesName =
                opts?.w?.config?.series?.[opts.seriesIndex]?.name || "";
              if (seriesName.toLowerCase().includes("valor")) {
                return val.toLocaleString("pt-BR", {
                  style: "currency",
                  currency: "BRL",
                });
              }
              return val;
            },
          },
        },
        legend: {
          show: true,
          formatter: function (seriesName: any, opts: any) {
            const i = opts.seriesIndex;
            const valores = opts.w.config.series[i]?.data || [];
            const total = valores.reduce((a: any, b: any) => a + b, 0);
            return `${seriesName}: ${total}`;
          },
        },
      },
      series,
    };
  }

  function formatarLinha(dados: any) {
    const categories = dados.map((item: any) =>
      formatarCategoria(item[chaveLabel])
    );
    const series = chavesSeries.map((serie) => ({
      name: serie.nome,
      data: dados.map((item: any) => Number(item[serie.campo])),
    }));

    const { yaxes, valorIdx } = montarYAxes(series);

    return {
      options: {
        chart: { type: "line" },
        xaxis: { categories },
        yaxis: yaxes,
        stroke: { curve: "smooth" },
        dataLabels: {
          enabled: true,
          enabledOnSeries: valorIdx, // rótulos apenas nas séries de valor
          formatter: function (val: any, opts: any) {
            const sName =
              opts?.w?.config?.series?.[opts.seriesIndex]?.name || "";
            const isValor = sName.toLowerCase().includes("valor");
            const isMil = sName.toLowerCase().includes("mil");
            return isValor ? fmtMoeda(val, isMil) : `${val}`;
          },
          offsetY: -8,
          style: { fontSize: "10px" },
          background: { enabled: true, borderRadius: 4, padding: 2 },
        },
        tooltip: {
          shared: true,
          intersect: false,
          y: {
            formatter: function (val: any, opts: any) {
              const sName =
                opts?.w?.config?.series?.[opts.seriesIndex]?.name || "";
              const isValor = sName.toLowerCase().includes("valor");
              const isMil = sName.toLowerCase().includes("mil");
              return isValor ? fmtMoeda(val, isMil) : val;
            },
          },
        },
        legend: {
          show: true,
          formatter: function (seriesName: any, opts: any) {
            const vals = opts.w.config.series[opts.seriesIndex]?.data || [];
            const total = vals.reduce(
              (a: number, b: number) => a + (Number(b) || 0),
              0
            );
            const isValor = String(seriesName).toLowerCase().includes("valor");
            const isMil = String(seriesName).toLowerCase().includes("mil");
            return isValor
              ? `${seriesName}: ${fmtMoeda(total, isMil)}`
              : `${seriesName}: ${total}`;
          },
        },
      },
      series,
    };
  }

  return (
    <div className="bg-white rounded ml-3 p-4 mt-3 w-1/1 dark:bg-boxdark dark:text-white">
      <p className="font-semibold text-center">{nomeGrafico}</p>
      <div className="justify-end flex mb-3">
        <Tabs defaultValue={tipo}>
          <TabsList className="shadow-none bg-[#f4f4f5] rounded-lg">
            {tiposPadrao
              .filter((t) => tiposGrafico.includes(t.value))
              .map((e) => (
                <TabsTrigger
                  key={e.value}
                  onClick={() => setTipo(e.value)}
                  className="shadow-none border-none"
                  value={e.value}
                >
                  {e.label}
                </TabsTrigger>
              ))}
          </TabsList>
        </Tabs>
      </div>

      {loading ? (
        <div className="flex justify-center items-center">
          <LoaderSun />
        </div>
      ) : (
        <>
          {(() => {
            const totais = calcularTotaisPropostas(dados);
            if (!totais) return null;
            const totalGeral = totais.totais; // ou use serieTotalQtde
            const totalValorGeral = totais.valorTotais;

            const linhas = [
              {
                label: "Total de Propostas Geradas",
                qtd: totais.geradas,
                valor: totais.valorGeradas,
              },
              {
                label: "Total de Propostas Aprovadas",
                qtd: totais.aprovadas,
                valor: totais.valorAprovadas,
              },
              {
                label: "Total de Propostas Canceladas",
                qtd: totais.canceladas,
                valor: totais.valorCanceladas,
              },
              {
                label: "Total Geral",
                qtd: totalGeral,
                valor: totalValorGeral,
                destaque: true,
              },
            ];

            return (
              <div className="flex flex-wrap gap-x-6 gap-y-1 justify-center text-sm mb-2 pr-1">
                {linhas.map((l) => (
                  <span
                    key={l.label}
                    className={`${l.destaque ? "font-bold" : "font-medium"} text-gray-700 dark:text-gray-200`}
                  >
                    {l.label}:{" "}
                    <span className="text-gray-900 dark:text-white">
                      {l.qtd}
                      {l.valor ? ` (${fmtMoeda(l.valor)})` : ""}
                    </span>
                  </span>
                ))}
              </div>
            );
          })()}
          <Grafico
            key={tipo}
            tipo={tipo}
            dados={dados}
            formatar={{
              Barra: formatarBarra,
              Pizza: formatarPizza,
              Linha: formatarLinha,
              Area: formatarArea,
            }}
          />
        </>
      )}
    </div>
  );
};

export default GraficoDinamico;
