/* global React, Icon, Badge, Button, brl, calcPeriod, calcPreviousPeriod, PeriodDropdown, PERIODOS_PRESET, ChartCanvas */

// ─── FilterDropdown ──────────────────────────────────────────────────────────
// Dropdown reutilizavel para filtros avancados (canal, vendedor, marca etc.)

function FilterDropdown({ label, icon, value, options, onChange }) {
  const hasValue = value && value !== '';
  return (
    <select
      value={value || ''}
      onChange={e => onChange(e.target.value)}
      style={{
        height: 32, padding: '0 8px 0 10px', borderRadius: 6,
        background: hasValue ? 'rgba(201,163,107,0.10)' : 'var(--tm-bg-2)',
        border: `1px solid ${hasValue ? 'rgba(201,163,107,0.3)' : 'var(--tm-line-2)'}`,
        color: hasValue ? 'var(--tm-brand-champagne)' : 'var(--tm-fg-2)',
        fontSize: 12, fontFamily: 'inherit', cursor: 'pointer',
        outline: 'none', maxWidth: 160,
      }}
    >
      <option value="">{label}</option>
      {options.map(o => <option key={o} value={o}>{o}</option>)}
    </select>
  );
}

// ─── RelFilterBar ────────────────────────────────────────────────────────────
// Barra horizontal de filtros. Fase 2: suporta filtros avancados via children + reset completo.

const DEFAULT_FILTERS = { periodId: '30d', customStart: '', customEnd: '', canal: '', vendedor: '', marca: '', linha: '', estado: '', formaPgto: '', status: '' };

function RelFilterBar({ filters, setFilters, children }) {
  const [open, setOpen] = React.useState(false);
  const { periodId, customStart, customEnd } = filters;

  const { start, end } = calcPeriod(periodId, customStart, customEnd);
  const label = PERIODOS_PRESET.find(p => p.id === periodId)?.label || 'Este mes';
  const rangeLabel = periodId === 'custom'
    ? `${start.toLocaleDateString('pt-BR',{day:'2-digit',month:'2-digit'})} - ${end.toLocaleDateString('pt-BR',{day:'2-digit',month:'2-digit'})}`
    : label;

  const hasExtraFilters = ['canal','vendedor','marca','linha','estado','formaPgto','status'].some(k => filters[k]);
  const isDirty = periodId !== '30d' || hasExtraFilters;

  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap',
      padding: '12px 0', marginBottom: 8,
    }}>
      {/* Periodo */}
      <div style={{ position: 'relative' }}>
        <button
          onClick={() => setOpen(!open)}
          style={{
            display: 'flex', alignItems: 'center', gap: 7,
            height: 32, padding: '0 12px', borderRadius: 6,
            background: 'var(--tm-bg-2)', border: '1px solid var(--tm-line-2)',
            color: 'var(--tm-fg-1)', fontSize: 12.5, cursor: 'pointer',
            fontFamily: 'inherit', fontWeight: 500,
          }}
        >
          <Icon name="calendar" size={13} />
          {rangeLabel}
          <Icon name="chevron-down" size={12} style={{ marginLeft: 2, opacity: 0.5 }} />
        </button>
        {open && (
          <PeriodDropdown
            periodId={periodId}
            setPeriodId={(id) => setFilters(f => ({ ...f, periodId: id }))}
            customStart={customStart}
            setCustomStart={(v) => setFilters(f => ({ ...f, customStart: v }))}
            customEnd={customEnd}
            setCustomEnd={(v) => setFilters(f => ({ ...f, customEnd: v }))}
            onClose={() => setOpen(false)}
          />
        )}
      </div>

      {/* Slots para filtros adicionais */}
      {children}

      {/* Spacer */}
      <div style={{ flex: 1 }} />

      {/* Limpar filtros */}
      {isDirty && (
        <button
          onClick={() => setFilters(DEFAULT_FILTERS)}
          style={{
            display: 'flex', alignItems: 'center', gap: 5,
            height: 28, padding: '0 10px', borderRadius: 5,
            background: 'transparent', border: 'none',
            color: 'var(--tm-fg-3)', fontSize: 11.5, cursor: 'pointer',
            fontFamily: 'inherit',
          }}
        >
          <Icon name="x" size={12} />
          Limpar filtros
        </button>
      )}
    </div>
  );
}

// ─── CompareKPI ──────────────────────────────────────────────────────────────

function CompareKPI({ label, current, previous, format, onClick, sub, loading }) {
  const formatValue = (v) => {
    if (v === null || v === undefined) return '...';
    switch (format) {
      case 'currency': return `R$ ${brl(v)}`;
      case 'percent': return `${v.toFixed(1)}%`;
      case 'number':
      default: return typeof v === 'number' ? v.toLocaleString('pt-BR') : String(v);
    }
  };

  const delta = (previous != null && previous !== 0 && current != null)
    ? ((current - previous) / Math.abs(previous)) * 100
    : null;

  const alertLevel = delta !== null
    ? (delta > 10 ? 'up' : delta < -10 ? 'down' : 'stable')
    : null;

  const deltaColor = alertLevel === 'up' ? 'var(--tm-success)'
    : alertLevel === 'down' ? 'var(--tm-danger)'
    : 'var(--tm-fg-3)';

  const deltaIcon = alertLevel === 'up' ? 'trending-up'
    : alertLevel === 'down' ? 'trending-down'
    : 'minus';

  return (
    <div
      onClick={onClick}
      style={{
        background: 'var(--tm-bg-2)',
        borderRadius: 'var(--tm-radius-md)',
        boxShadow: 'inset 0 0 0 1px var(--tm-line-1)',
        padding: '16px 18px',
        display: 'flex', flexDirection: 'column', gap: 4,
        cursor: onClick ? 'pointer' : 'default',
        transition: 'transform .12s',
        minWidth: 0,
      }}
      onMouseEnter={e => { if (onClick) e.currentTarget.style.transform = 'translateY(-2px)'; }}
      onMouseLeave={e => { e.currentTarget.style.transform = 'none'; }}
    >
      <div style={{
        fontSize: 10.5, letterSpacing: '0.12em', textTransform: 'uppercase',
        color: 'var(--tm-fg-3)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
      }}>{label}</div>

      <div style={{
        fontSize: 22, fontWeight: 600, fontVariantNumeric: 'tabular-nums',
        letterSpacing: '-0.01em', color: 'var(--tm-fg-1)',
      }}>
        {loading ? '...' : formatValue(current)}
      </div>

      <div style={{ display: 'flex', alignItems: 'center', gap: 6, minHeight: 18 }}>
        {delta !== null && !loading && (
          <>
            <Icon name={deltaIcon} size={12} style={{ color: deltaColor }} />
            <span style={{ fontSize: 11.5, fontWeight: 500, color: deltaColor }}>
              {delta > 0 ? '+' : ''}{delta.toFixed(1)}%
            </span>
            <span style={{ fontSize: 11, color: 'var(--tm-fg-4)' }}>vs anterior</span>
          </>
        )}
        {delta === null && sub && !loading && (
          <span style={{ fontSize: 11, color: 'var(--tm-fg-4)' }}>{sub}</span>
        )}
      </div>

      {alertLevel && !loading && <AlertIndicator level={alertLevel} />}
    </div>
  );
}

// ─── AlertIndicator ──────────────────────────────────────────────────────────

function AlertIndicator({ level, label }) {
  const config = {
    up: { bg: 'rgba(91,177,122,0.12)', color: 'var(--tm-success)', text: label || 'Crescendo', icon: 'trending-up' },
    stable: { bg: 'rgba(212,160,74,0.12)', color: '#D4A04A', text: label || 'Estavel', icon: 'minus' },
    down: { bg: 'rgba(217,101,94,0.12)', color: 'var(--tm-danger)', text: label || 'Em queda', icon: 'trending-down' },
  };
  const c = config[level] || config.stable;

  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      height: 18, padding: '0 7px', borderRadius: 9,
      background: c.bg, marginTop: 2,
    }}>
      <Icon name={c.icon} size={10} style={{ color: c.color }} />
      <span style={{ fontSize: 10, fontWeight: 500, color: c.color }}>{c.text}</span>
    </div>
  );
}

// ─── EvolutionChart ──────────────────────────────────────────────────────────
// Grafico de linha Chart.js com toggle diario / semanal / mensal.

function EvolutionChart({ pedidos, start, end }) {
  const [granularity, setGranularity] = React.useState('diario');

  const chartData = React.useMemo(() => {
    if (!pedidos || pedidos.length === 0) return null;

    const grouped = {};
    pedidos.forEach(p => {
      const dt = new Date(p.data_venda || p.created_at);
      let key;
      if (granularity === 'diario') {
        key = dt.toISOString().slice(0, 10);
      } else if (granularity === 'semanal') {
        const d = new Date(dt);
        d.setDate(d.getDate() - d.getDay());
        key = d.toISOString().slice(0, 10);
      } else {
        key = dt.toISOString().slice(0, 7);
      }
      if (!grouped[key]) grouped[key] = 0;
      grouped[key] += parseFloat(p.total) || 0;
    });

    const sorted = Object.entries(grouped).sort((a, b) => a[0].localeCompare(b[0]));
    const labels = sorted.map(([k]) => {
      if (granularity === 'mensal') {
        const [y, m] = k.split('-');
        return new Date(y, m - 1).toLocaleDateString('pt-BR', { month: 'short', year: '2-digit' });
      }
      const d = new Date(k + 'T12:00:00');
      return d.toLocaleDateString('pt-BR', { day: '2-digit', month: '2-digit' });
    });
    const values = sorted.map(([, v]) => v);

    return {
      labels,
      datasets: [{
        data: values,
        borderColor: '#C9A36B',
        backgroundColor: 'rgba(201,163,107,0.08)',
        borderWidth: 2,
        fill: true,
        tension: 0.3,
        pointRadius: granularity === 'diario' && values.length > 30 ? 0 : 3,
        pointHoverRadius: 5,
        pointBackgroundColor: '#C9A36B',
      }],
    };
  }, [pedidos, granularity]);

  const options = {
    scales: {
      x: {
        grid: { color: 'rgba(255,255,255,0.04)' },
        ticks: { color: 'rgba(255,255,255,0.45)', font: { size: 10 }, maxTicksLimit: 12 },
      },
      y: {
        grid: { color: 'rgba(255,255,255,0.04)' },
        ticks: {
          color: 'rgba(255,255,255,0.45)', font: { size: 10 },
          callback: (v) => v >= 1000 ? `${(v/1000).toFixed(0)}k` : v,
        },
        beginAtZero: true,
      },
    },
    plugins: {
      legend: { display: false },
      tooltip: {
        backgroundColor: 'rgba(11,11,13,0.92)',
        callbacks: {
          label: (ctx) => `R$ ${brl(ctx.parsed.y)}`,
        },
      },
    },
  };

  return (
    <div>
      <div style={{ display: 'flex', gap: 4, marginBottom: 12 }}>
        {[
          { id: 'diario', label: 'Diario' },
          { id: 'semanal', label: 'Semanal' },
          { id: 'mensal', label: 'Mensal' },
        ].map(g => (
          <span
            key={g.id}
            className={`chip${granularity === g.id ? ' active' : ''}`}
            style={{ cursor: 'pointer', fontSize: 11 }}
            onClick={() => setGranularity(g.id)}
          >
            {g.label}
          </span>
        ))}
      </div>
      {!chartData ? (
        <div style={{ height: 200, display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--tm-fg-3)', fontSize: 13 }}>
          Sem dados para o grafico
        </div>
      ) : (
        <ChartCanvas type="line" data={chartData} options={options} height={220} />
      )}
    </div>
  );
}

// ─── FunnelChart ──────────────────────────────────────────────────────────────
// Funil operacional: Em andamento -> Separacao -> Faturado -> Atendido

function FunnelChart({ pedidosPorStatus }) {
  const stages = [
    { key: 'Em andamento', label: 'Em andamento', color: '#6BA3D6' },
    { key: 'Separação',    label: 'Separacao',    color: '#D4A04A' },
    { key: 'Faturado',     label: 'Faturado',     color: '#C9A36B' },
    { key: 'Atendido',     label: 'Atendido',     color: '#5BB17A' },
  ];

  const maxCount = Math.max(...stages.map(s => pedidosPorStatus[s.key] || 0), 1);

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
      {stages.map((s, i) => {
        const count = pedidosPorStatus[s.key] || 0;
        const pct = maxCount > 0 ? (count / maxCount) * 100 : 0;
        const prevCount = i > 0 ? (pedidosPorStatus[stages[i - 1].key] || 0) : null;
        const convRate = prevCount && prevCount > 0 ? ((count / prevCount) * 100).toFixed(0) : null;

        return (
          <div key={s.key}>
            <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 4 }}>
              <span style={{ fontSize: 12, color: 'var(--tm-fg-2)' }}>{s.label}</span>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                {convRate && (
                  <span style={{ fontSize: 10, color: 'var(--tm-fg-4)' }}>{convRate}% conv.</span>
                )}
                <span style={{ fontSize: 12, fontWeight: 600, fontVariantNumeric: 'tabular-nums', color: 'var(--tm-fg-1)' }}>{count}</span>
              </div>
            </div>
            <div style={{ background: 'var(--tm-bg-2)', borderRadius: 4, height: 24, overflow: 'hidden', position: 'relative' }}>
              <div style={{
                width: `${Math.max(pct, 2)}%`, height: '100%',
                background: s.color, borderRadius: 4,
                transition: 'width 0.4s ease',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>
                {pct > 15 && <span style={{ fontSize: 10, fontWeight: 600, color: '#0B0B0D' }}>{pct.toFixed(0)}%</span>}
              </div>
            </div>
          </div>
        );
      })}
    </div>
  );
}

// ─── RankingBar ───────────────────────────────────────────────────────────────
// Barra de progresso relativa ao #1 para rankings

function RankingBar({ items, valueKey, labelKey, formatFn, maxItems }) {
  const top = (items || []).slice(0, maxItems || 10);
  const maxVal = top.length > 0 ? top[0][valueKey] : 1;

  if (top.length === 0) {
    return <div style={{ padding: 24, textAlign: 'center', color: 'var(--tm-fg-3)', fontSize: 12.5 }}>Sem dados</div>;
  }

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
      {top.map((item, i) => (
        <div key={item[labelKey] || i} style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <div style={{ width: 20, fontSize: 11, fontWeight: 700, color: i < 3 ? 'var(--tm-brand-champagne)' : 'var(--tm-fg-4)', textAlign: 'right' }}>{i + 1}</div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 3 }}>
              <span style={{ fontSize: 12, color: 'var(--tm-fg-1)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{item[labelKey]}</span>
              <span style={{ fontSize: 11, color: 'var(--tm-fg-2)', fontVariantNumeric: 'tabular-nums', flexShrink: 0, marginLeft: 8 }}>
                {formatFn ? formatFn(item[valueKey]) : item[valueKey]}
              </span>
            </div>
            <div style={{ background: 'var(--tm-bg-2)', borderRadius: 3, height: 4, overflow: 'hidden' }}>
              <div style={{ width: `${Math.max((item[valueKey] / maxVal) * 100, 2)}%`, height: '100%', background: 'var(--tm-brand-champagne)', borderRadius: 3, transition: 'width 0.3s' }} />
            </div>
          </div>
        </div>
      ))}
    </div>
  );
}

// ─── DistClassBadge ──────────────────────────────────────────────────────────
// Classificacao automatica de distribuidores: Bronze / Prata / Ouro / Diamante

function DistClassBadge({ fat, pedidos, ciclo }) {
  let tier, tone;
  if (fat >= 50000 && pedidos >= 10) { tier = 'Diamante'; tone = 'brand'; }
  else if (fat >= 20000 && pedidos >= 5) { tier = 'Ouro'; tone = 'warning'; }
  else if (fat >= 5000 && pedidos >= 2) { tier = 'Prata'; tone = 'info'; }
  else { tier = 'Bronze'; tone = 'neutral'; }

  return <Badge tone={tone}>{tier}</Badge>;
}

// ─── IBGE_TO_UF (para mapa) ─────────────────────────────────────────────────
const IBGE_TO_UF_REL = {
  11:'RO',12:'AC',13:'AM',14:'RR',15:'PA',16:'AP',17:'TO',
  21:'MA',22:'PI',23:'CE',24:'RN',25:'PB',26:'PE',27:'AL',28:'SE',29:'BA',
  31:'MG',32:'ES',33:'RJ',35:'SP',
  41:'PR',42:'SC',43:'RS',
  50:'MS',51:'MT',52:'GO',53:'DF',
};

// ─── CurvaABCChart ──────────────────────────────────────────────────────────
// Combo chart: barras individuais + linha cumulativa %. A=80%, B=15%, C=5%

function CurvaABCChart({ items, labelKey, valueKey, height }) {
  const sorted = [...(items || [])].sort((a, b) => b[valueKey] - a[valueKey]);
  const total = sorted.reduce((a, it) => a + (it[valueKey] || 0), 0);
  if (sorted.length === 0 || total === 0) {
    return <div style={{ height: height || 260, display:'flex', alignItems:'center', justifyContent:'center', color:'var(--tm-fg-3)', fontSize:13 }}>Sem dados</div>;
  }

  let cum = 0;
  const cumPcts = sorted.map(it => { cum += it[valueKey] || 0; return (cum / total) * 100; });
  const colors = sorted.map((_, i) => cumPcts[i] <= 80 ? '#C9A36B' : cumPcts[i] <= 95 ? '#6BA3D6' : '#94a3b8');
  const labels = sorted.map(it => {
    const l = it[labelKey] || '';
    return l.length > 14 ? l.slice(0, 12) + '..' : l;
  });

  const data = {
    labels,
    datasets: [
      {
        type: 'bar',
        data: sorted.map(it => it[valueKey]),
        backgroundColor: colors,
        borderRadius: 3,
        yAxisID: 'y',
        order: 2,
      },
      {
        type: 'line',
        data: cumPcts,
        borderColor: '#D9655E',
        borderWidth: 2,
        pointRadius: 0,
        tension: 0.2,
        yAxisID: 'y1',
        order: 1,
      },
    ],
  };

  const options = {
    scales: {
      x: { grid: { display: false }, ticks: { color: 'rgba(255,255,255,0.45)', font: { size: 9 }, maxRotation: 45 } },
      y: { grid: { color: 'rgba(255,255,255,0.04)' }, ticks: { color: 'rgba(255,255,255,0.45)', font: { size: 10 }, callback: v => v >= 1000 ? `${(v/1000).toFixed(0)}k` : v }, beginAtZero: true },
      y1: { position: 'right', grid: { display: false }, ticks: { color: '#D9655E', font: { size: 10 }, callback: v => `${v.toFixed(0)}%` }, min: 0, max: 100 },
    },
    plugins: {
      legend: { display: false },
      tooltip: { backgroundColor: 'rgba(11,11,13,0.92)', callbacks: { label: ctx => ctx.datasetIndex === 0 ? `R$ ${brl(ctx.parsed.y)}` : `${ctx.parsed.y.toFixed(1)}% acumulado` } },
      annotation: {
        annotations: {
          line80: { type: 'line', yMin: 80, yMax: 80, yScaleID: 'y1', borderColor: 'rgba(201,163,107,0.4)', borderDash: [4,4], borderWidth: 1 },
          line95: { type: 'line', yMin: 95, yMax: 95, yScaleID: 'y1', borderColor: 'rgba(107,163,214,0.4)', borderDash: [4,4], borderWidth: 1 },
        },
      },
    },
  };

  return <ChartCanvas type="bar" data={data} options={options} height={height || 260} />;
}

// ─── AgingChart ──────────────────────────────────────────────────────────────
// Doughnut chart for aging de inadimplencia

function AgingChart({ faixas, height }) {
  if (!faixas || faixas.every(f => f.valor === 0)) {
    return <div style={{ height: height || 200, display:'flex', alignItems:'center', justifyContent:'center', color:'var(--tm-fg-3)', fontSize:13 }}>Nenhum titulo vencido</div>;
  }

  const data = {
    labels: faixas.map(f => f.label),
    datasets: [{
      data: faixas.map(f => f.valor),
      backgroundColor: ['#5BB17A', '#D4A04A', '#D9655E', '#9B2C2C'],
      borderWidth: 0,
    }],
  };

  const options = {
    cutout: '60%',
    plugins: {
      legend: { display: true, position: 'bottom', labels: { color: 'rgba(255,255,255,0.5)', font: { size: 10 }, boxWidth: 10, padding: 8 } },
      tooltip: { backgroundColor: 'rgba(11,11,13,0.92)', callbacks: { label: ctx => `${ctx.label}: R$ ${brl(ctx.parsed)}` } },
    },
  };

  return <ChartCanvas type="doughnut" data={data} options={options} height={height || 200} />;
}

// ─── FrequenciaHistograma ────────────────────────────────────────────────────
// Bar chart showing purchase frequency distribution

function FrequenciaHistograma({ faixas, height }) {
  if (!faixas || faixas.length === 0) {
    return <div style={{ height: height || 200, display:'flex', alignItems:'center', justifyContent:'center', color:'var(--tm-fg-3)', fontSize:13 }}>Sem dados</div>;
  }

  const data = {
    labels: faixas.map(f => f.label),
    datasets: [{
      data: faixas.map(f => f.count),
      backgroundColor: faixas.map((_, i) => {
        const colors = ['#94a3b8', '#6BA3D6', '#C9A36B', '#5BB17A', '#D4A04A'];
        return colors[i % colors.length];
      }),
      borderRadius: 4,
    }],
  };

  const options = {
    scales: {
      x: { grid: { display: false }, ticks: { color: 'rgba(255,255,255,0.45)', font: { size: 10 } } },
      y: { grid: { color: 'rgba(255,255,255,0.04)' }, ticks: { color: 'rgba(255,255,255,0.45)', font: { size: 10 } }, beginAtZero: true },
    },
    plugins: { legend: { display: false }, tooltip: { backgroundColor: 'rgba(11,11,13,0.92)' } },
  };

  return <ChartCanvas type="bar" data={data} options={options} height={height || 200} />;
}

// ─── RelExportMenu (placeholder Fase 4) ──────────────────────────────────────

function RelExportMenu({ onCSV, disabled }) {
  return (
    <Button variant="secondary" icon="download" size="sm" onClick={onCSV} disabled={disabled}>
      Exportar CSV
    </Button>
  );
}

// ─── Helpers ─────────────────────────────────────────────────────────────────

const relFmtDate = (iso) => {
  if (!iso) return '—';
  const d = new Date(iso);
  return isNaN(d) ? iso : d.toLocaleDateString('pt-BR', { day: '2-digit', month: '2-digit', year: '2-digit' });
};

// ─── Export ──────────────────────────────────────────────────────────────────
Object.assign(window, {
  FilterDropdown, RelFilterBar, DEFAULT_FILTERS,
  CompareKPI, AlertIndicator, RelExportMenu, relFmtDate,
  EvolutionChart, FunnelChart, RankingBar, DistClassBadge,
  IBGE_TO_UF_REL, CurvaABCChart, AgingChart, FrequenciaHistograma,
});
