import React, { useState, useMemo, useCallback } from 'react';
import { Line, Bar, Pie } from 'react-chartjs-2';
import {
  filterDataByDateRange, calculateMetrics,
  getUniqueChannels, getUniqueMuseums, getUniqueDistricts,
  groupByMuseum, groupByChannel, groupByDistrict,
  umrahData,
} from '../services/dataService';
import { chartColors, chartPalette, createBaseOptions } from '../config/chartConfig';
import type { MuseumRecord, Season } from '../types';
import { useLanguage } from '../contexts/LanguageContext';
import { EN, AR } from '../lib/locale';
import { currentMonth, shiftYear } from '../lib/dateHelpers';
import PeriodHero from './shared/PeriodPicker';
import AltMultiSelect from './shared/AltMultiSelect';
import MetricCard from './shared/MetricCard';

interface Props {
  data: MuseumRecord[];
  seasons: Season[];
  includeVAT: boolean;
  setIncludeVAT: (v: boolean) => void;
  allowedMuseums: string[] | null;
  allowedChannels: string[] | null;
  lang?: 'en' | 'ar';
}

// ─── main page ────────────────────────────────────────────────────
export default function DashboardDemo({ data, seasons: _seasons, includeVAT, setIncludeVAT, allowedMuseums, allowedChannels }: Props) {
  const { lang: activeLang, setLanguage } = useLanguage();
  const L = activeLang === 'ar' ? AR : EN;
  const curr = currentMonth();
  const [start, setStart] = useState(curr.start);
  const [end,   setEnd]   = useState(curr.end);
  const [selDistricts, setSelDistricts] = useState<string[]>([]);
  const [selChannels,  setSelChannels]  = useState<string[]>([]);
  const [selMuseums,   setSelMuseums]   = useState<string[]>([]);
  const [metric, setMetric] = useState('revenue');
  const [gran,   setGran]   = useState('week');
  const [museumChartType,   setMuseumChartType]   = useState<'bar'|'pie'>('bar');
  const [channelChartType,  setChannelChartType]  = useState<'bar'|'pie'>('pie');
  const [districtChartType, setDistrictChartType] = useState<'bar'|'pie'>('pie');
  const [museumDisplayMode,   setMuseumDisplayMode]   = useState<'absolute'|'percent'>('absolute');
  const [channelDisplayMode,  setChannelDisplayMode]  = useState<'absolute'|'percent'>('absolute');
  const [districtDisplayMode, setDistrictDisplayMode] = useState<'absolute'|'percent'>('absolute');

  const perm = useMemo(() => {
    if (!allowedMuseums || !allowedChannels) return [];
    let d = data;
    if (allowedMuseums.length) d = d.filter(r => allowedMuseums.includes(r.museum_name));
    if (allowedChannels.length) d = d.filter(r => allowedChannels.includes(r.channel));
    return d;
  }, [data, allowedMuseums, allowedChannels]);

  const availableYears = useMemo(() => {
    const s = new Set<number>(); perm.forEach(r => r.date && s.add(parseInt(r.date.slice(0,4))));
    const a = Array.from(s).sort((a,b) => b-a); return a.length ? a : [new Date().getFullYear()];
  }, [perm]);

  const allDistricts = useMemo(() => getUniqueDistricts(perm), [perm]);
  const allChannels  = useMemo(() => getUniqueChannels(perm),  [perm]);
  const allMuseums   = useMemo(() => getUniqueMuseums(perm),   [perm]);

  const applyFilters = useCallback((rows: MuseumRecord[]) => {
    let d = rows;
    if (selChannels.length)  d = d.filter(r => selChannels.includes(r.channel));
    if (selMuseums.length)   d = d.filter(r => selMuseums.includes(r.museum_name));
    if (selDistricts.length) d = d.filter(r => selDistricts.includes(r.district));
    return d;
  }, [selDistricts, selChannels, selMuseums]);

  const filteredData = useMemo(() => applyFilters(filterDataByDateRange(perm, start, end, {})), [perm, start, end, applyFilters]);
  const prevStart = shiftYear(start), prevEnd = shiftYear(end);
  const prevData  = useMemo(() => applyFilters(filterDataByDateRange(perm, prevStart, prevEnd, {})), [perm, prevStart, prevEnd, applyFilters]);

  const currM = useMemo(() => calculateMetrics(filteredData, includeVAT), [filteredData, includeVAT]);
  const prevM = useMemo(() => calculateMetrics(prevData,    includeVAT), [prevData,    includeVAT]);

  const revenueField = includeVAT ? 'revenue_gross' : 'revenue_net';

  const getVal = useCallback((rows: MuseumRecord[], m: string) => {
    if (m==='avgRevenue') {
      const rev = rows.reduce((s,r) => s + parseFloat(String((r as any)[revenueField]||0)), 0);
      const vis = rows.reduce((s,r) => s + parseInt(String(r.visits||0)), 0);
      return vis>0 ? rev/vis : 0;
    }
    const f: Record<string,string> = { revenue: revenueField, visitors:'visits', tickets:'tickets' };
    return rows.reduce((s,r) => s + parseFloat(String((r as any)[f[m]]||0)), 0);
  }, [revenueField]);

  const trendResult = useMemo(() => {
    const group = (rows: MuseumRecord[], ps: string) => {
      const s = new Date(ps); const acc: Record<number, MuseumRecord[]> = {};
      rows.forEach(r => {
        if (!r.date) return;
        const diff = Math.floor((new Date(r.date).getTime() - s.getTime()) / 86400000);
        const key = gran==='month' ? Math.floor(diff/30)+1 : gran==='week' ? Math.floor(diff/7)+1 : diff+1;
        if (!acc[key]) acc[key]=[]; acc[key].push(r);
      });
      const res: Record<number,number> = {};
      Object.entries(acc).forEach(([k,v]) => res[Number(k)] = getVal(v, metric)); return res;
    };
    const pg = group(prevData, prevStart), cg = group(filteredData, start);
    const maxK = Math.max(...Object.keys(pg).map(Number), ...Object.keys(cg).map(Number), 1);
    const s0 = new Date(start);
    const fmt = (d: Date) => d.toLocaleDateString('en-GB', { day: 'numeric', month: 'short' });
    const labels = Array.from({length:maxK}, (_,i) =>
      gran==='week' ? `W${i+1}` : gran==='month' ? L.monthShort[(s0.getMonth()+i)%12] : `D${i+1}`
    );
    const tooltipLabels = Array.from({length:maxK}, (_,i) => {
      if (gran==='week') {
        const ws = new Date(s0.getTime() + i * 7 * 86400000);
        const we = new Date(s0.getTime() + (i+1) * 7 * 86400000 - 86400000);
        return `Week ${i+1}  ·  ${fmt(ws)} – ${fmt(we)}`;
      }
      if (gran==='month') {
        const ms = new Date(s0.getFullYear(), s0.getMonth() + i, 1);
        return ms.toLocaleDateString('en-GB', { month: 'long', year: 'numeric' });
      }
      const ds = new Date(s0.getTime() + i * 86400000);
      return ds.toLocaleDateString('en-GB', { day: 'numeric', month: 'long', year: 'numeric' });
    });
    const prevYear = parseInt(start.slice(0,4))-1;
    return {
      tooltipLabels,
      data: {
        labels,
        datasets: [
          { label:`${prevYear}`, data:labels.map((_,i) => pg[i+1]||0), borderColor:chartColors.muted, backgroundColor:'transparent', borderWidth:1.5, tension:0.4, pointRadius:0, borderDash:[4,3] },
          { label:start.slice(0,4), data:labels.map((_,i) => cg[i+1]||0), borderColor:chartColors.primary, backgroundColor:chartColors.primary+'18', borderWidth:2.5, tension:0.4, fill:true, pointRadius:gran==='week'?3:1, pointBackgroundColor:chartColors.primary },
        ]
      }
    };
  }, [filteredData, prevData, prevStart, start, metric, gran, getVal, L]);
  const trendData = trendResult.data;

  const museumData = useMemo(() => {
    const g = groupByMuseum(filteredData, includeVAT);
    const getM = (d: typeof g[string]) => metric==='visitors' ? d.visitors : metric==='tickets' ? d.tickets : d.revenue;
    const entries = Object.entries(g).sort((a,b) => getM(b[1]) - getM(a[1]));
    return { labels:entries.map(([k]) => k), datasets:[{ label:metric, data:entries.map(([,v]) => getM(v)), backgroundColor:chartPalette, borderRadius:4 }] };
  }, [filteredData, includeVAT, metric]);

  const channelData = useMemo(() => {
    const g = groupByChannel(filteredData, includeVAT);
    const getM = (d: typeof g[string]) => metric==='visitors' ? d.visitors : metric==='tickets' ? d.tickets : d.revenue;
    const entries = Object.entries(g).sort((a,b) => getM(b[1]) - getM(a[1]));
    return { labels:entries.map(([k]) => k), datasets:[{ label:metric, data:entries.map(([,v]) => getM(v)), backgroundColor:chartPalette, borderRadius:4 }] };
  }, [filteredData, includeVAT, metric]);

  const districtData = useMemo(() => {
    const g = groupByDistrict(filteredData, includeVAT);
    const getM = (d: typeof g[string]) => metric==='visitors' ? d.visitors : metric==='tickets' ? d.tickets : d.revenue;
    const entries = Object.entries(g).sort((a,b) => getM(b[1]) - getM(a[1]));
    return { labels:entries.map(([k]) => k), datasets:[{ label:metric, data:entries.map(([,v]) => getM(v)), backgroundColor:chartPalette.map(c => c+'cc'), borderRadius:4 }] };
  }, [filteredData, includeVAT, metric]);

  const toPercent = (chartData: any) => {
    const total = chartData.datasets[0].data.reduce((s: number, v: number) => s+v, 0);
    if (total===0) return chartData;
    return { ...chartData, datasets: [{ ...chartData.datasets[0], data: chartData.datasets[0].data.map((v: number) => parseFloat(((v/total)*100).toFixed(1))) }] };
  };

  const museumDisplay   = useMemo(() => museumDisplayMode==='percent' ? toPercent(museumData)   : museumData,   [museumData,   museumDisplayMode]);
  const channelDisplay  = useMemo(() => channelDisplayMode==='percent' ? toPercent(channelData)  : channelData,  [channelData,  channelDisplayMode]);
  const districtDisplay = useMemo(() => districtDisplayMode==='percent' ? toPercent(districtData) : districtData, [districtData, districtDisplayMode]);

  const estimatePilgrims = useCallback((s: string, e: string) => {
    const sd=new Date(s), ed=new Date(e); let total=0, has=false;
    for (let y=sd.getFullYear(); y<=ed.getFullYear(); y++) {
      for (let q=1; q<=4; q++) {
        const qs=new Date(y,(q-1)*3,1), qe=new Date(y,q*3,0);
        if (qe<sd||qs>ed) continue;
        const p=umrahData[y]?.[q]; if (!p) continue;
        const os=new Date(Math.max(qs.getTime(),sd.getTime())), oe=new Date(Math.min(qe.getTime(),ed.getTime()));
        total+=p*((oe.getTime()-os.getTime())/86400000+1)/((qe.getTime()-qs.getTime())/86400000+1); has=true;
      }
    }
    return has ? Math.round(total) : null;
  }, []);

  const currPilgrims = useMemo(() => estimatePilgrims(start, end), [start, end, estimatePilgrims]);
  const prevPilgrims = useMemo(() => estimatePilgrims(prevStart, prevEnd), [prevStart, prevEnd, estimatePilgrims]);
  const currCapture  = currPilgrims ? currM.visitors/currPilgrims*100 : null;
  const prevCapture  = prevPilgrims ? prevM.visitors/prevPilgrims*100 : null;

  const baseOpts  = useMemo(() => createBaseOptions(false), []);
  const { chartOpts, barHorizOpts, barNoLegend } = useMemo(() => {
    const chartOpts: any = { ...baseOpts, plugins:{ ...baseOpts.plugins, legend:{ position:'top', align:'end', labels:{ boxWidth:10, padding:10, font:{ size:11 } } } } };
    const barHorizOpts: any = { ...chartOpts, indexAxis:'y', plugins:{ ...chartOpts.plugins, legend:{ display:false } } };
    const barNoLegend: any  = { ...chartOpts, plugins:{ ...chartOpts.plugins, legend:{ display:false } } };
    return { chartOpts, barHorizOpts, barNoLegend };
  }, [baseOpts]);
  const trendOpts: any = useMemo(() => ({
    ...chartOpts,
    plugins: {
      ...chartOpts.plugins,
      tooltip: {
        ...chartOpts.plugins.tooltip,
        callbacks: {
          title: (items: any[]) => trendResult.tooltipLabels[items[0]?.dataIndex] ?? items[0]?.label,
        }
      }
    }
  }), [chartOpts, trendResult.tooltipLabels]);

  const pieOptions: any = useMemo(() => ({
    responsive: true, maintainAspectRatio: false,
    plugins: {
      legend: { display:true, position:'right', labels:{ boxWidth:12, padding:10, font:{ size:11 }, color:'#64748b' } },
      tooltip: baseOpts.plugins.tooltip,
      datalabels: { display:false },
    }
  }), [baseOpts]);

  const metricOpts = [{ value:'revenue', label:L.revenue }, { value:'visitors', label:L.visitors }, { value:'tickets', label:L.tickets }];
  const granOpts   = [{ value:'day', label:L.daily }, { value:'week', label:L.weekly }, { value:'month', label:L.monthly }];
  const hasFilters = selDistricts.length>0 || selChannels.length>0 || selMuseums.length>0;
  const activeFilterCount = selDistricts.length + selChannels.length + selMuseums.length;
  const [filtersOpen, setFiltersOpen] = useState(false);

  return (
    <div
      className="alt-page"
      dir={L.dir}
      style={{
        '--alt-body-font': L.bodyFont,
        '--alt-display-font': L.displayFont,
        '--alt-mono-font': L.monoFont,
      } as React.CSSProperties}
    >
      <h1 className="alt-page-title">{L.pageTitle}</h1>
      <p className="alt-page-sub">{L.pageSub}</p>

      <PeriodHero start={start} end={end} onChange={(s,e) => { setStart(s); setEnd(e); }} availableYears={availableYears} L={L} />

      <div className={`alt-filter-bar${filtersOpen ? ' alt-filter-bar--open' : ''}`}>
        <div className="alt-filter-head">
          <span className="alt-filter-label">{L.filter}</span>
          {activeFilterCount > 0 && <span className="alt-filter-badge">{activeFilterCount}</span>}
          <button type="button" className="alt-filter-toggle" onClick={() => setFiltersOpen(v => !v)} aria-expanded={filtersOpen} aria-label="Toggle filters">
            <svg className={`alt-filter-chevron${filtersOpen ? ' alt-filter-chevron--open' : ''}`} width="14" height="14" viewBox="0 0 10 10" fill="none">
              <path d="M2 3.5L5 6.5L8 3.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
          </button>
        </div>
        <div className="alt-filter-body">
          <div className="alt-filter-sep" />
          <AltMultiSelect value={selDistricts} options={allDistricts} onChange={setSelDistricts} allLabel={L.allDistricts} countLabel={L.countDistricts} clearLabel={L.clearSel} />
          <AltMultiSelect value={selChannels}  options={allChannels}  onChange={setSelChannels}  allLabel={L.allChannels}  countLabel={L.countChannels}  clearLabel={L.clearSel} />
          <AltMultiSelect value={selMuseums}   options={allMuseums}   onChange={setSelMuseums}   allLabel={L.allMuseums}   countLabel={L.countMuseums}   clearLabel={L.clearSel} />
          {hasFilters && <button type="button" className="alt-filter-reset" onClick={() => { setSelDistricts([]); setSelChannels([]); setSelMuseums([]); }}>{L.reset}</button>}
          <div className="alt-filter-spacer" />
          <div className="alt-vat-toggle">
            <button type="button" className={`alt-vat-opt${!includeVAT?' alt-vat-opt--on':''}`} onClick={() => setIncludeVAT(false)}>{L.exclVAT}</button>
            <button type="button" className={`alt-vat-opt${includeVAT ?' alt-vat-opt--on':''}`} onClick={() => setIncludeVAT(true)}>{L.inclVAT}</button>
          </div>
        </div>
      </div>

      <div className="alt-section-heading"><h2>{L.keyMetrics}</h2></div>
      <div className="alt-metrics">
        <MetricCard title={L.revenue}     curr={currM.revenue}          prev={prevM.revenue}          isCurrency newLabel={L.newLabel} />
        <MetricCard title={L.visitors}    curr={currM.visitors}         prev={prevM.visitors}                    newLabel={L.newLabel} />
        <MetricCard title={L.tickets}     curr={currM.tickets}          prev={prevM.tickets}                     newLabel={L.newLabel} />
        <MetricCard title={L.avgRev}      curr={currM.avgRevPerVisitor} prev={prevM.avgRevPerVisitor} isCurrency newLabel={L.newLabel} />
        {currPilgrims!==null && prevPilgrims!==null &&
          <MetricCard title={L.pilgrims}  curr={currPilgrims}           prev={prevPilgrims}                      newLabel={L.newLabel} />}
        {currCapture!==null && prevCapture!==null &&
          <MetricCard title={L.captureRate} curr={parseFloat(currCapture.toFixed(2))} prev={parseFloat((prevCapture??0).toFixed(2))} newLabel={L.newLabel} />}
      </div>

      <div className="alt-section-heading"><h2>{L.charts}</h2></div>
      <div className="dalt-charts-grid">

        <div className="alt-chart-card dalt-chart-full">
          <div className="alt-chart-header">
            <h3 className="alt-chart-title">{L.trendTitle}</h3>
            <div className="alt-chart-controls">
              {metricOpts.map(o => <button key={o.value} type="button" aria-pressed={metric===o.value} className={`alt-ctrl${metric===o.value?' alt-ctrl-on':''}`} onClick={() => setMetric(o.value)}>{o.label}</button>)}
              <div className="alt-ctrl-sep" />
              {granOpts.map(o => <button key={o.value} type="button" aria-pressed={gran===o.value} className={`alt-ctrl${gran===o.value?' alt-ctrl-on':''}`} onClick={() => setGran(o.value)}>{o.label}</button>)}
            </div>
          </div>
          <div className="alt-chart-wrap alt-chart-wrap--tall"><Line data={trendData} options={trendOpts} /></div>
        </div>

        <div className="alt-chart-card">
          <div className="alt-chart-header">
            <h3 className="alt-chart-title">{L.museumTitle}</h3>
            <div className="alt-chart-controls">
              {metricOpts.map(o => <button key={o.value} type="button" aria-pressed={metric===o.value} className={`alt-ctrl${metric===o.value?' alt-ctrl-on':''}`} onClick={() => setMetric(o.value)}>{o.label}</button>)}
              <div className="alt-ctrl-sep" />
              <button type="button" aria-pressed={museumChartType==='bar'} className={`alt-ctrl${museumChartType==='bar'?' alt-ctrl-on':''}`} onClick={() => setMuseumChartType('bar')}>{L.barLabel}</button>
              <button type="button" aria-pressed={museumChartType==='pie'} className={`alt-ctrl${museumChartType==='pie'?' alt-ctrl-on':''}`} onClick={() => setMuseumChartType('pie')}>{L.pieLabel}</button>
              <div className="alt-ctrl-sep" />
              <button type="button" aria-pressed={museumDisplayMode==='absolute'} className={`alt-ctrl${museumDisplayMode==='absolute'?' alt-ctrl-on':''}`} onClick={() => setMuseumDisplayMode('absolute')}>{L.absLabel}</button>
              <button type="button" aria-pressed={museumDisplayMode==='percent'} className={`alt-ctrl${museumDisplayMode==='percent'?' alt-ctrl-on':''}`} onClick={() => setMuseumDisplayMode('percent')}>{L.pctLabel}</button>
            </div>
          </div>
          <div className="alt-chart-wrap alt-chart-wrap--tall">
            {museumChartType==='pie' ? <Pie data={museumDisplay} options={pieOptions} /> : <Bar data={museumDisplay} options={barHorizOpts} />}
          </div>
        </div>

        <div className="alt-chart-card">
          <div className="alt-chart-header">
            <h3 className="alt-chart-title">{L.channelTitle}</h3>
            <div className="alt-chart-controls">
              {metricOpts.map(o => <button key={o.value} type="button" aria-pressed={metric===o.value} className={`alt-ctrl${metric===o.value?' alt-ctrl-on':''}`} onClick={() => setMetric(o.value)}>{o.label}</button>)}
              <div className="alt-ctrl-sep" />
              <button type="button" aria-pressed={channelChartType==='bar'} className={`alt-ctrl${channelChartType==='bar'?' alt-ctrl-on':''}`} onClick={() => setChannelChartType('bar')}>{L.barLabel}</button>
              <button type="button" aria-pressed={channelChartType==='pie'} className={`alt-ctrl${channelChartType==='pie'?' alt-ctrl-on':''}`} onClick={() => setChannelChartType('pie')}>{L.pieLabel}</button>
              <div className="alt-ctrl-sep" />
              <button type="button" aria-pressed={channelDisplayMode==='absolute'} className={`alt-ctrl${channelDisplayMode==='absolute'?' alt-ctrl-on':''}`} onClick={() => setChannelDisplayMode('absolute')}>{L.absLabel}</button>
              <button type="button" aria-pressed={channelDisplayMode==='percent'} className={`alt-ctrl${channelDisplayMode==='percent'?' alt-ctrl-on':''}`} onClick={() => setChannelDisplayMode('percent')}>{L.pctLabel}</button>
            </div>
          </div>
          <div className="alt-chart-wrap">
            {channelChartType==='pie' ? <Pie data={channelDisplay} options={pieOptions} /> : <Bar data={channelDisplay} options={barNoLegend} />}
          </div>
        </div>

        <div className="alt-chart-card dalt-chart-full">
          <div className="alt-chart-header">
            <h3 className="alt-chart-title">{L.districtTitle}</h3>
            <div className="alt-chart-controls">
              {metricOpts.map(o => <button key={o.value} type="button" aria-pressed={metric===o.value} className={`alt-ctrl${metric===o.value?' alt-ctrl-on':''}`} onClick={() => setMetric(o.value)}>{o.label}</button>)}
              <div className="alt-ctrl-sep" />
              <button type="button" aria-pressed={districtChartType==='bar'} className={`alt-ctrl${districtChartType==='bar'?' alt-ctrl-on':''}`} onClick={() => setDistrictChartType('bar')}>{L.barLabel}</button>
              <button type="button" aria-pressed={districtChartType==='pie'} className={`alt-ctrl${districtChartType==='pie'?' alt-ctrl-on':''}`} onClick={() => setDistrictChartType('pie')}>{L.pieLabel}</button>
              <div className="alt-ctrl-sep" />
              <button type="button" aria-pressed={districtDisplayMode==='absolute'} className={`alt-ctrl${districtDisplayMode==='absolute'?' alt-ctrl-on':''}`} onClick={() => setDistrictDisplayMode('absolute')}>{L.absLabel}</button>
              <button type="button" aria-pressed={districtDisplayMode==='percent'} className={`alt-ctrl${districtDisplayMode==='percent'?' alt-ctrl-on':''}`} onClick={() => setDistrictDisplayMode('percent')}>{L.pctLabel}</button>
            </div>
          </div>
          <div className="alt-chart-wrap">
            {districtChartType==='pie' ? <Pie data={districtDisplay} options={pieOptions} /> : <Bar data={districtDisplay} options={barNoLegend} />}
          </div>
        </div>

      </div>
    </div>
  );
}
