$(function () {
  $("#estadistica").addClass("active");
  moment.locale("es");

  const moneda = $("#moneda").val() || "S/";
  const hoy = moment();
  const inicioMes = hoy.clone().startOf("month");
  const $fechaInicio = $("#fecha_ini_est");
  const $fechaFin = $("#fecha_fin_est");
  const $rangoTexto = $("#estadistica_rango_texto");
  let estadisticaCache = null;

  let g1Chart = null;
  let g2Chart = null;
  let g3Chart = null;
  let g4Chart = null;
  let g5Chart = null;
  let g6Chart = null;
  let g7Chart = null;
  let g8Chart = null;
  let g9Chart = null;
  let g10Chart = null;
  let g11Chart = null;
  let g12Chart = null;
  let g13Chart = null;

  const $g1Chart = document.getElementById("chart1");
  const $g2Chart = document.getElementById("chart2");
  const $g3Chart = document.getElementById("chart3");
  const $g4Chart = document.getElementById("chart4");
  const $g5Chart = document.getElementById("chart5");
  const $g6Chart = document.getElementById("chart6");
  const $g7Chart = document.getElementById("chart7");
  const $g8Chart = document.getElementById("chart8");
  const $g9Chart = document.getElementById("chart9");
  const $g10Chart = document.getElementById("chart10");
  const $g11Chart = document.getElementById("chart11");
  const $g12Chart = document.getElementById("chart12");
  const $g13Chart = document.getElementById("chart13");

  $fechaInicio.val(inicioMes.format("YYYY-MM-DD"));
  $fechaFin.val(hoy.format("YYYY-MM-DD"));

  function formatearNumero(value) {
    if (typeof formatNumber === "function") {
      return formatNumber(value || 0);
    }

    return (parseFloat(value || 0) || 0).toFixed(2);
  }

  function destruirGrafico(chart) {
    if (chart) {
      chart.destroy();
    }
  }

  function obtenerRangoActivo() {
    let inicio = $fechaInicio.val();
    let fin = $fechaFin.val();

    if (!inicio) {
      inicio = inicioMes.format("YYYY-MM-DD");
      $fechaInicio.val(inicio);
    }

    if (!fin) {
      fin = hoy.format("YYYY-MM-DD");
      $fechaFin.val(fin);
    }

    if (moment(inicio).isAfter(fin)) {
      const temporal = inicio;
      inicio = fin;
      fin = temporal;
      $fechaInicio.val(inicio);
      $fechaFin.val(fin);
    }

    return {
      inicio: inicio,
      fin: fin,
    };
  }

  function actualizarTextoRango(rango) {
    if (!rango || !rango.inicio || !rango.fin) {
      return;
    }

    $rangoTexto.text(
      "Rango activo: " +
        moment(rango.inicio, "YYYY-MM-DD").format("DD-MM-YYYY") +
        " al " +
        moment(rango.fin, "YYYY-MM-DD").format("DD-MM-YYYY")
    );
  }

  function normalizarSerie(labels, data, emptyLabel) {
    if (!Array.isArray(labels) || !labels.length) {
      return {
        labels: [emptyLabel],
        data: [0],
        empty: true,
      };
    }

    return {
      labels: labels,
      data: data,
      empty: false,
    };
  }

  function obtenerTooltipMoneda(datasetKey, opsKey) {
    return {
      callbacks: {
        label: function (tooltipItem, dataChart) {
          const dataset = dataChart.datasets[tooltipItem.datasetIndex] || {};
          const value = (dataset[datasetKey] || [])[tooltipItem.index] || 0;
          return "Ventas " + moneda + " " + formatearNumero(value);
        },
        afterLabel: function (tooltipItem, dataChart) {
          const dataset = dataChart.datasets[tooltipItem.datasetIndex] || {};
          if (!opsKey) {
            return "";
          }

          const operaciones = (dataset[opsKey] || [])[tooltipItem.index] || 0;
          return "Operaciones: " + operaciones;
        },
      },
    };
  }

  function obtenerTooltipCantidadMoneda(cantidadKey, ventasKey, cantidadLabel) {
    return {
      callbacks: {
        label: function (tooltipItem, dataChart) {
          const dataset = dataChart.datasets[tooltipItem.datasetIndex] || {};
          const cantidad = (dataset[cantidadKey] || [])[tooltipItem.index] || 0;
          return (cantidadLabel || "Cantidad") + ": " + cantidad;
        },
        afterLabel: function (tooltipItem, dataChart) {
          const dataset = dataChart.datasets[tooltipItem.datasetIndex] || {};
          const ventas = (dataset[ventasKey] || [])[tooltipItem.index] || 0;
          return "Ventas " + moneda + " " + formatearNumero(ventas);
        },
      },
    };
  }

  function renderGraficoMozos(rows) {
    const mostrarTotal = $("#mozos_tipo").val() === "2";
    const labels = [];
    const data = [];

    (Array.isArray(rows) ? rows : []).forEach(function (item) {
      labels.push(item.nombres || "Sin mozo");
      data.push(
        mostrarTotal
          ? parseFloat(item.total_ventas) || 0
          : parseInt(item.numero_ventas, 10) || 0
      );
    });

    const serie = normalizarSerie(labels, data, "Sin datos");

    destruirGrafico(g1Chart);
    g1Chart = new Chart($g1Chart, {
      type: "bar",
      data: {
        labels: serie.labels,
        datasets: [
          {
            label: mostrarTotal ? "Total en Ventas S/" : "Pedidos atendidos",
            data: serie.data,
            fill: false,
            backgroundColor: "rgba(75, 192, 192, 0.2)",
            borderColor: "rgb(54, 162, 235)",
            borderWidth: 1,
          },
        ],
      },
      options: {
        scales: {
          yAxes: [{ ticks: { beginAtZero: true } }],
        },
      },
    });
  }

  function renderGraficoComprasVentas(grafico) {
    const labels = Array.isArray(grafico.labels) ? grafico.labels : [];
    const ventas = Array.isArray(grafico.ventas) ? grafico.ventas : [];
    const compras = Array.isArray(grafico.compras) ? grafico.compras : [];
    const serie = normalizarSerie(labels, ventas, "Sin datos");

    destruirGrafico(g2Chart);
    g2Chart = new Chart($g2Chart, {
      type: "bar",
      data: {
        labels: serie.labels,
        datasets: [
          {
            label: "Compras S/",
            data: serie.empty ? [0] : compras,
            backgroundColor: "rgba(255, 0, 0, 0.5)",
            borderColor: "rgba(255, 0, 0, 1)",
            borderWidth: 1,
          },
          {
            label: "Ventas S/",
            data: serie.data,
            backgroundColor: "rgba(47, 255, 92, 0.5)",
            borderColor: "rgba(47, 255, 92, 1)",
            borderWidth: 1,
          },
        ],
      },
      options: {
        scales: {
          yAxes: [{ ticks: { beginAtZero: true } }],
        },
      },
    });
  }

  function renderGraficoVentasDia(grafico) {
    const serie = normalizarSerie(
      Array.isArray(grafico.labels) ? grafico.labels : [],
      Array.isArray(grafico.ventas) ? grafico.ventas : [],
      "Sin datos"
    );
    const operaciones = Array.isArray(grafico.operaciones)
      ? grafico.operaciones
      : [];

    destruirGrafico(g3Chart);
    g3Chart = new Chart($g3Chart, {
      type: "horizontalBar",
      data: {
        labels: serie.labels,
        datasets: [
          {
            label: "Total venta (S/)",
            data: serie.data,
            ventasMeta: serie.data,
            operacionesMeta: serie.empty ? [0] : operaciones,
            fill: false,
            backgroundColor: [
              "rgba(54, 162, 235, 0.65)",
              "rgba(255, 99, 132, 0.65)",
              "rgba(255, 159, 64, 0.65)",
              "rgba(255, 205, 86, 0.65)",
              "rgba(75, 192, 192, 0.65)",
              "rgba(153, 102, 255, 0.65)",
              "rgba(201, 203, 207, 0.75)",
            ],
            borderWidth: 1,
          },
        ],
      },
      options: {
        scales: {
          xAxes: [{ ticks: { beginAtZero: true } }],
        },
        tooltips: obtenerTooltipMoneda("ventasMeta", "operacionesMeta"),
      },
    });
  }

  function renderGraficoVentasMes(grafico) {
    const serie = normalizarSerie(
      Array.isArray(grafico.labels) ? grafico.labels : [],
      Array.isArray(grafico.ventas) ? grafico.ventas : [],
      "Sin datos"
    );

    destruirGrafico(g4Chart);
    g4Chart = new Chart($g4Chart, {
      type: "line",
      data: {
        labels: serie.labels,
        datasets: [
          {
            fill: false,
            lineTension: 0.15,
            backgroundColor: ["rgb(252, 75, 108)"],
            borderColor: ["rgba(252, 75, 108, 0.65)"],
            label: "Total venta (S/)",
            data: serie.data,
            borderWidth: 2,
            pointRadius: 3,
          },
        ],
      },
      options: {
        scales: {
          yAxes: [{ ticks: { beginAtZero: true } }],
        },
      },
    });
  }

  function renderGraficoVentasFecha(grafico) {
    const serie = normalizarSerie(
      Array.isArray(grafico.labels) ? grafico.labels : [],
      Array.isArray(grafico.ventas) ? grafico.ventas : [],
      "Sin datos"
    );
    const operaciones = Array.isArray(grafico.operaciones)
      ? grafico.operaciones
      : [];

    destruirGrafico(g9Chart);
    g9Chart = new Chart($g9Chart, {
      type: "line",
      data: {
        labels: serie.labels,
        datasets: [
          {
            label: "Total venta (S/)",
            data: serie.data,
            ventasMeta: serie.data,
            operacionesMeta: serie.empty ? [0] : operaciones,
            fill: false,
            lineTension: 0.15,
            backgroundColor: "rgba(124, 77, 255, 0.15)",
            borderColor: "rgba(124, 77, 255, 0.85)",
            borderWidth: 2,
            pointRadius: 3,
            pointHoverRadius: 5,
            pointBackgroundColor: "rgba(124, 77, 255, 1)",
          },
        ],
      },
      options: {
        scales: {
          yAxes: [{ ticks: { beginAtZero: true } }],
        },
        tooltips: obtenerTooltipMoneda("ventasMeta", "operacionesMeta"),
      },
    });
  }

  function renderGraficoDeliveryPorFecha(grafico) {
    const serie = normalizarSerie(
      Array.isArray(grafico.labels) ? grafico.labels : [],
      Array.isArray(grafico.pedidos) ? grafico.pedidos : [],
      "Sin datos"
    );
    const ventas = Array.isArray(grafico.ventas) ? grafico.ventas : [];

    destruirGrafico(g10Chart);
    g10Chart = new Chart($g10Chart, {
      type: "line",
      data: {
        labels: serie.labels,
        datasets: [
          {
            label: "Pedidos delivery",
            data: serie.data,
            pedidosMeta: serie.data,
            ventasMeta: serie.empty ? [0] : ventas,
            fill: false,
            lineTension: 0.15,
            backgroundColor: "rgba(244, 67, 54, 0.12)",
            borderColor: "rgba(244, 67, 54, 0.85)",
            borderWidth: 2,
            pointRadius: 3,
            pointHoverRadius: 5,
            pointBackgroundColor: "rgba(244, 67, 54, 1)",
          },
        ],
      },
      options: {
        scales: {
          yAxes: [{ ticks: { beginAtZero: true } }],
        },
        tooltips: obtenerTooltipCantidadMoneda(
          "pedidosMeta",
          "ventasMeta",
          "Pedidos"
        ),
      },
    });
  }

  function renderGraficoCanal(grafico) {
    const mesa = parseFloat(grafico.mesa) || 0;
    const llevar = parseFloat(grafico.llevar) || 0;
    const delivery = parseFloat(grafico.delivery) || 0;
    const total = mesa + llevar + delivery;

    let labels = ["Salon S/", "Llevar S/", "Delivery S/"];
    let data = [mesa, llevar, delivery];
    let colors = ["#36a2eb", "#ff6384", "#ffcd56"];

    if (total <= 0) {
      labels = ["Sin datos"];
      data = [1];
      colors = ["#d6dbe1"];
    }

    destruirGrafico(g5Chart);
    g5Chart = new Chart($g5Chart, {
      type: "pie",
      data: {
        labels: labels,
        datasets: [
          {
            backgroundColor: colors,
            data: data,
          },
        ],
      },
    });
  }

  function renderGraficoDelivery(rows) {
    const labels = [];
    const pedidos = [];
    const totales = [];

    (Array.isArray(rows) ? rows : []).forEach(function (item) {
      labels.push(item.repartidor || "Sin repartidor");
      pedidos.push(parseInt(item.pedidos, 10) || 0);
      totales.push(parseFloat(item.total) || 0);
    });

    const serie = normalizarSerie(labels, pedidos, "Sin registros");

    destruirGrafico(g6Chart);
    g6Chart = new Chart($g6Chart, {
      type: "bar",
      data: {
        labels: serie.labels,
        datasets: [
          {
            label: "Total de Pedidos",
            data: serie.data,
            ventasMeta: serie.empty ? [0] : totales,
            fill: false,
            backgroundColor: "rgba(228, 0, 46, 0.2)",
            borderColor: "rgb(228, 0, 46)",
            borderWidth: 1,
          },
        ],
      },
      options: {
        scales: {
          yAxes: [{ ticks: { beginAtZero: true } }],
        },
        tooltips: obtenerTooltipMoneda("ventasMeta"),
      },
    });
  }

  function renderGraficoTipoDocumento(rows) {
    const labels = [];
    const totales = [];
    const operaciones = [];

    (Array.isArray(rows) ? rows : []).forEach(function (item) {
      labels.push(item.documento || "Sin documento");
      totales.push(parseFloat(item.total) || 0);
      operaciones.push(parseInt(item.operaciones, 10) || 0);
    });

    const serie = normalizarSerie(labels, totales, "Sin datos");

    destruirGrafico(g7Chart);
    g7Chart = new Chart($g7Chart, {
      type: "doughnut",
      data: {
        labels: serie.labels,
        datasets: [
          {
            data: serie.data,
            ventasMeta: serie.data,
            operacionesMeta: serie.empty ? [0] : operaciones,
            backgroundColor: [
              "#1e88e5",
              "#43a047",
              "#fb8c00",
              "#8e24aa",
              "#e53935",
              "#546e7a",
            ],
          },
        ],
      },
      options: {
        tooltips: obtenerTooltipMoneda("ventasMeta", "operacionesMeta"),
      },
    });
  }

  function renderGraficoMedioPago(grafico) {
    const serie = normalizarSerie(
      Array.isArray(grafico.labels) ? grafico.labels : [],
      Array.isArray(grafico.ventas) ? grafico.ventas : [],
      "Sin datos"
    );
    const operaciones = Array.isArray(grafico.operaciones)
      ? grafico.operaciones
      : [];

    destruirGrafico(g8Chart);
    g8Chart = new Chart($g8Chart, {
      type: "bar",
      data: {
        labels: serie.labels,
        datasets: [
          {
            label: "Ventas S/",
            data: serie.data,
            ventasMeta: serie.data,
            operacionesMeta: serie.empty ? [0] : operaciones,
            backgroundColor: [
              "#2e7d32",
              "#1565c0",
              "#00acc1",
              "#5e35b1",
              "#fb8c00",
            ],
            borderWidth: 1,
          },
        ],
      },
      options: {
        scales: {
          yAxes: [{ ticks: { beginAtZero: true } }],
        },
        tooltips: obtenerTooltipMoneda("ventasMeta", "operacionesMeta"),
      },
    });
  }

  function renderGraficoTopPlatos(rows) {
    const labels = [];
    const cantidades = [];
    const totales = [];

    (Array.isArray(rows) ? rows : []).forEach(function (item) {
      labels.push(item.producto || "Sin nombre");
      cantidades.push(parseFloat(item.cantidad) || 0);
      totales.push(parseFloat(item.total) || 0);
    });

    const serie = normalizarSerie(labels, cantidades, "Sin datos");

    destruirGrafico(g11Chart);
    g11Chart = new Chart($g11Chart, {
      type: "horizontalBar",
      data: {
        labels: serie.labels,
        datasets: [
          {
            label: "Cantidad vendida",
            data: serie.data,
            cantidadMeta: serie.data,
            ventasMeta: serie.empty ? [0] : totales,
            backgroundColor: "rgba(67, 160, 71, 0.65)",
            borderColor: "rgba(67, 160, 71, 1)",
            borderWidth: 1,
          },
        ],
      },
      options: {
        scales: {
          xAxes: [{ ticks: { beginAtZero: true } }],
        },
        tooltips: obtenerTooltipCantidadMoneda(
          "cantidadMeta",
          "ventasMeta",
          "Cantidad"
        ),
      },
    });
  }

  function renderGraficoTopProductos(rows) {
    const labels = [];
    const cantidades = [];
    const totales = [];

    (Array.isArray(rows) ? rows : []).forEach(function (item) {
      labels.push(item.producto || "Sin nombre");
      cantidades.push(parseFloat(item.cantidad) || 0);
      totales.push(parseFloat(item.total) || 0);
    });

    const serie = normalizarSerie(labels, cantidades, "Sin datos");

    destruirGrafico(g12Chart);
    g12Chart = new Chart($g12Chart, {
      type: "horizontalBar",
      data: {
        labels: serie.labels,
        datasets: [
          {
            label: "Cantidad vendida",
            data: serie.data,
            cantidadMeta: serie.data,
            ventasMeta: serie.empty ? [0] : totales,
            backgroundColor: "rgba(30, 136, 229, 0.65)",
            borderColor: "rgba(30, 136, 229, 1)",
            borderWidth: 1,
          },
        ],
      },
      options: {
        scales: {
          xAxes: [{ ticks: { beginAtZero: true } }],
        },
        tooltips: obtenerTooltipCantidadMoneda(
          "cantidadMeta",
          "ventasMeta",
          "Cantidad"
        ),
      },
    });
  }

  function renderGraficoTopClientes(rows) {
    const labels = [];
    const totales = [];
    const operaciones = [];
    const tickets = [];

    (Array.isArray(rows) ? rows : []).forEach(function (item) {
      labels.push(item.cliente || "Sin cliente");
      totales.push(parseFloat(item.total) || 0);
      operaciones.push(parseInt(item.operaciones, 10) || 0);
      tickets.push(parseFloat(item.ticket_promedio) || 0);
    });

    const serie = normalizarSerie(labels, totales, "Sin datos");

    destruirGrafico(g13Chart);
    g13Chart = new Chart($g13Chart, {
      type: "horizontalBar",
      data: {
        labels: serie.labels,
        datasets: [
          {
            label: "Consumo total",
            data: serie.data,
            ventasMeta: serie.data,
            operacionesMeta: serie.empty ? [0] : operaciones,
            ticketMeta: serie.empty ? [0] : tickets,
            backgroundColor: "rgba(123, 31, 162, 0.65)",
            borderColor: "rgba(123, 31, 162, 1)",
            borderWidth: 1,
          },
        ],
      },
      options: {
        scales: {
          xAxes: [{ ticks: { beginAtZero: true } }],
        },
        tooltips: {
          callbacks: {
            label: function (tooltipItem, dataChart) {
              const dataset = dataChart.datasets[tooltipItem.datasetIndex] || {};
              const total = (dataset.ventasMeta || [])[tooltipItem.index] || 0;
              return "Consumo " + moneda + " " + formatearNumero(total);
            },
            afterLabel: function (tooltipItem, dataChart) {
              const dataset = dataChart.datasets[tooltipItem.datasetIndex] || {};
              const ops = (dataset.operacionesMeta || [])[tooltipItem.index] || 0;
              const ticket = (dataset.ticketMeta || [])[tooltipItem.index] || 0;
              return [
                "Operaciones: " + ops,
                "Ticket promedio: " + moneda + " " + formatearNumero(ticket),
              ];
            },
          },
        },
      },
    });
  }

  function renderizar(payload) {
    estadisticaCache = payload || {};
    actualizarTextoRango(payload.rango || obtenerRangoActivo());
    renderGraficoMozos(payload.grafico1 || []);
    renderGraficoComprasVentas(payload.grafico2 || {});
    renderGraficoVentasDia(payload.grafico3 || {});
    renderGraficoVentasMes(payload.grafico4 || {});
    renderGraficoCanal(payload.grafico5 || {});
    renderGraficoDelivery(payload.grafico6 || []);
    renderGraficoTipoDocumento(payload.grafico7 || []);
    renderGraficoMedioPago(payload.grafico8 || {});
    renderGraficoVentasFecha(payload.grafico9 || {});
    renderGraficoDeliveryPorFecha(payload.grafico10 || {});
    renderGraficoTopPlatos(payload.grafico11 || []);
    renderGraficoTopProductos(payload.grafico12 || []);
    renderGraficoTopClientes(payload.grafico13 || []);
  }

  function cargarEstadisticas() {
    const rango = obtenerRangoActivo();

    $.ajax({
      type: "POST",
      url: $("#url").val() + "estadistica/estadistica_datos",
      data: {
        fecha_ini: rango.inicio,
        fecha_fin: rango.fin,
      },
      dataType: "json",
      success: function (payload) {
        renderizar(payload);
      },
    });
  }

  $("#btn-filtrar-estadistica").on("click", function () {
    cargarEstadisticas();
  });

  $("#btn-estadistica-mes-actual").on("click", function () {
    $fechaInicio.val(inicioMes.format("YYYY-MM-DD"));
    $fechaFin.val(hoy.format("YYYY-MM-DD"));
    cargarEstadisticas();
  });

  $("#mozos_tipo").on("change", function () {
    if (estadisticaCache) {
      renderGraficoMozos(estadisticaCache.grafico1 || []);
      return;
    }

    cargarEstadisticas();
  });

  actualizarTextoRango({
    inicio: $fechaInicio.val(),
    fin: $fechaFin.val(),
  });

  cargarEstadisticas();
});
