import { useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import {
  Area,
  AreaChart,
  CartesianGrid,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from 'recharts';
import { AiLabel } from '../../components/ui/Badge';
import { Button } from '../../components/ui/Button';
import { EmptyState, ErrorState, Skeleton } from '../../components/ui/States';
import { IconAnalytics, IconPie, IconSettlement } from '../../components/ui/icons';
import { CHART } from '../chartColors';
import { analyticsApi } from '../../api/endpoints';
import { ApiRequestError } from '../../api/client';
import { useResolvedEventId } from '../../hooks/useResolvedEventId';
import type {
  AnalyticsData,
  AnalyticsKpi,
  AnalyticsPeriod,
  AnalyticsPerspective,
} from '../../api/types';
import {
  EXHIBITOR_KPIS,
  EXHIBITOR_PERF,
  OPERATOR_KPIS,
  OPERATOR_PNL,
  SECTORS,
} from './sampleAnalytics';
import { GlobalOverviewSection } from './GlobalOverviewSection';
import { AiConsolePanel } from './AiConsolePanel';
import './analytics.css';

/*
 * SCR-13 경영분석 대시보드 (M16 BI). Stitch business_intelligence 이식.
 * 정상 경로: GET /api/events/{eventId}/analytics?perspective&period (실집계 — 매출·부스 추이·손익).
 * 관점(운영사/참가업체)·기간 토글이 쿼리 파라미터를 구동 → 실 refetch.
 * 폴백: NETWORK/NOT_FOUND 시에만 sampleAnalytics 로 강등. sectors·exhibitorPerf 원천 부재 시 백엔드 빈배열 → 빈 상태.
 */
export function AnalyticsDashboardPage() {
  const { t } = useTranslation();
  const [perspective, setPerspective] = useState<AnalyticsPerspective>('operator');
  const [period, setPeriod] = useState<AnalyticsPeriod>('event');
  const eventId = useResolvedEventId();
  const isOperator = perspective === 'operator';

  const q = useQuery({
    queryKey: ['analytics', eventId, perspective, period],
    queryFn: () => analyticsApi.get(eventId as string, perspective, period),
    enabled: !!eventId,
    retry: false,
  });

  const degraded = isDegradable(q.error);
  const data: AnalyticsData | null = q.data ?? (degraded ? fallback(perspective) : null);
  const hardError = q.isError && !degraded;

  return (
    <div className="kx-bi">
      <header className="kx-bi__head">
        <div>
          <h1 className="kx-bi__title">{t('analytics.title')}</h1>
          <p className="kx-bi__subtitle">{t('analytics.subtitle')}</p>
        </div>
        <div className="kx-bi__head-actions">
          <div className="kx-seg" role="tablist" aria-label={t('analytics.perspective')}>
            <button
              role="tab"
              aria-selected={isOperator}
              className={`kx-seg__btn ${isOperator ? 'is-active' : ''}`}
              onClick={() => setPerspective('operator')}
            >
              {t('analytics.operator')}
            </button>
            <button
              role="tab"
              aria-selected={!isOperator}
              className={`kx-seg__btn ${!isOperator ? 'is-active' : ''}`}
              onClick={() => setPerspective('exhibitor')}
            >
              {t('analytics.exhibitor')}
            </button>
          </div>
          <select
            className="kx-select"
            aria-label={t('analytics.periodAria')}
            value={period}
            onChange={(e) => setPeriod(e.target.value as AnalyticsPeriod)}
          >
            <option value="event">{t('analytics.periodEvent')}</option>
            <option value="d90">{t('analytics.periodD90')}</option>
            <option value="annual">{t('analytics.periodAnnual')}</option>
          </select>
          <Button variant="secondary">{t('analytics.exportPdf')}</Button>
          <Button variant="secondary">{t('analytics.exportExcel')}</Button>
        </div>
      </header>

      {!eventId && (
        <EmptyState title={t('analytics.noEventTitle')} description={t('analytics.noEventDesc')} />
      )}

      {degraded && (
        <div className="kx-bi__degraded-bar">
          <span className="kx-bi__degraded">{t('analytics.offlineSample')}</span>
          {t('analytics.degradedMsg')}
        </div>
      )}

      {q.isLoading && <BiSkeleton />}

      {hardError && (
        <ErrorState message={t('analytics.loadError')} onRetry={() => q.refetch()} />
      )}

      {data && (
        <>
          {/* KPI 밴드 */}
          <section className="kx-bi__kpis" aria-label={t('analytics.kpisAria')}>
            {data.kpis.length === 0 ? (
              <EmptyState title={t('analytics.kpiEmpty')} />
            ) : (
              data.kpis.map((k, i) => <KpiCard key={`${k.label}-${i}`} kpi={k} />)
            )}
          </section>

          {/* 히어로 추세(2/3) + 업종 구성(1/3) */}
          <div className="kx-bi__split">
            <section className="kx-card kx-bi__trend" aria-label={t('analytics.trendAria')}>
              <div className="kx-card__head">
                <h2><IconAnalytics className="kx-title-ic" size={18} />{t('analytics.trendTitle')}</h2>
                <AiLabel>{t('analytics.monthlyAgg')}</AiLabel>
              </div>
              <p className="kx-card__hint">{t('analytics.trendHint')}</p>
              <div className="kx-bi__chart">
                {data.trend.length === 0 ? (
                  <EmptyState title={t('analytics.trendEmptyTitle')} description={t('analytics.trendEmptyDesc')} />
                ) : (
                  <ResponsiveContainer width="100%" height={320}>
                    <AreaChart data={data.trend} margin={{ top: 8, right: 12, bottom: 0, left: -8 }}>
                      <defs>
                        <linearGradient id="gRevenue" x1="0" y1="0" x2="0" y2="1">
                          <stop offset="0%" stopColor={CHART.primary600} stopOpacity={0.35} />
                          <stop offset="100%" stopColor={CHART.primary600} stopOpacity={0.02} />
                        </linearGradient>
                      </defs>
                      <CartesianGrid stroke={CHART.neutral200} strokeDasharray="3 3" vertical={false} />
                      <XAxis dataKey="period" tick={{ fontSize: 12, fill: CHART.slate }} tickLine={false} axisLine={{ stroke: CHART.neutral200 }} />
                      <YAxis yAxisId="rev" tick={{ fontSize: 12, fill: CHART.slate }} tickLine={false} axisLine={false} width={54} tickFormatter={(v) => shortWon(v as number)} />
                      <YAxis yAxisId="booth" orientation="right" tick={{ fontSize: 12, fill: CHART.slate }} tickLine={false} axisLine={false} width={36} />
                      <Tooltip
                        contentStyle={TOOLTIP_STYLE}
                        formatter={(value, _name, item) =>
                          item?.dataKey === 'revenue' ? formatWon(value as number) : t('analytics.boothsUnit', { n: (value as number).toLocaleString() })
                        }
                      />
                      <Area yAxisId="rev" type="monotone" dataKey="revenue" name={t('analytics.revenue')} stroke={CHART.primary600} fill="url(#gRevenue)" strokeWidth={2} />
                      <Area yAxisId="booth" type="monotone" dataKey="booths" name={t('analytics.booth')} stroke={CHART.aiAccent} fill={CHART.aiAccent} fillOpacity={0.08} strokeWidth={2} />
                    </AreaChart>
                  </ResponsiveContainer>
                )}
              </div>
            </section>

            <section className="kx-card kx-bi__sectors" aria-label={t('analytics.sectorsAria')}>
              <div className="kx-card__head">
                <h2><IconPie className="kx-title-ic" size={18} />{t('analytics.sectorsTitle')}</h2>
              </div>
              {data.sectors.length === 0 ? (
                <EmptyState
                  title={t('analytics.sectorsEmptyTitle')}
                  description={t('analytics.sectorsEmptyDesc')}
                />
              ) : (
                <ul className="kx-barlist">
                  {data.sectors.map((s) => (
                    <li key={s.name} className="kx-barlist__item">
                      <div className="kx-barlist__top">
                        <span>{s.name}</span>
                        <span className="tnum">{s.sharePercent.toFixed(1)}%</span>
                      </div>
                      <div className="kx-barlist__track">
                        <span className="kx-barlist__fill" style={{ width: `${s.sharePercent}%` }} />
                      </div>
                    </li>
                  ))}
                </ul>
              )}
            </section>
          </div>

          {/* 성과 테이블(전폭) */}
          <section className="kx-card kx-bi__table-card" aria-label={t('analytics.perfTable')}>
            <div className="kx-card__head">
              <h2><IconSettlement className="kx-title-ic" size={18} />{isOperator ? t('analytics.pnlTitle') : t('analytics.exhibitorPerfTitle')}</h2>
              {degraded && <span className="kx-bi__degraded">{t('analytics.sampleTag')}</span>}
            </div>
            <div className="kx-table-scroll">
              {isOperator ? (
                data.pnl.length === 0 ? (
                  <EmptyState title={t('analytics.pnlEmptyTitle')} description={t('analytics.pnlEmptyDesc')} />
                ) : (
                  <table className="kx-table kx-table--zebra">
                    <thead>
                      <tr>
                        <th>{t('analytics.colItem')}</th>
                        <th className="kx-num">{t('analytics.colAmount')}</th>
                        <th>{t('analytics.colGrade')}</th>
                      </tr>
                    </thead>
                    <tbody>
                      {data.pnl.map((r, i) => (
                        <tr key={`${r.item}-${i}`}>
                          <td>{r.item}</td>
                          <td className="kx-num tnum">{formatWon(r.amount)}</td>
                          <td><GradePill grade={r.grade} /></td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                )
              ) : data.exhibitorPerf.length === 0 ? (
                <EmptyState title={t('analytics.perfEmptyTitle')} description={t('analytics.perfEmptyDesc')} />
              ) : (
                <table className="kx-table kx-table--zebra">
                  <thead>
                    <tr>
                      <th>{t('analytics.colCompany')}</th>
                      <th className="kx-num">{t('analytics.colLeads')}</th>
                      <th className="kx-num">{t('analytics.colConversion')}</th>
                    </tr>
                  </thead>
                  <tbody>
                    {data.exhibitorPerf.map((r, i) => (
                      <tr key={`${r.companyName}-${i}`}>
                        <td>{r.companyName}</td>
                        <td className="kx-num tnum">{r.leads.toLocaleString()}</td>
                        <td className="kx-num tnum">{r.conversionPercent.toFixed(1)}%</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              )}
            </div>
          </section>
        </>
      )}

      {/* 테넌트 전역(행사 횡단) BI — 홀매니저 전용. 권한/오프라인 시 내부에서 숨김. */}
      <GlobalOverviewSection />

      {/* F092 자연어 조회(Text-to-SQL) + F025 규정 챗봇 — AI 라우터 경유(참고용·근거 표기). */}
      <AiConsolePanel />
    </div>
  );
}

const TOOLTIP_STYLE = {
  fontSize: 12,
  borderRadius: 8,
  border: '1px solid #E4E7EC',
  boxShadow: '0 4px 12px rgba(16,24,40,0.1)',
} as const;

function BiSkeleton() {
  return (
    <div aria-hidden="true" style={{ display: 'grid', gap: 16 }}>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12 }}>
        {[0, 1, 2, 3].map((i) => (
          <Skeleton key={i} height={92} radius={12} />
        ))}
      </div>
      <Skeleton height={320} radius={12} />
      <Skeleton height={220} radius={12} />
    </div>
  );
}

function KpiCard({ kpi }: { kpi: AnalyticsKpi }) {
  const dir = kpi.trend === 'down' ? 'down' : 'up';
  return (
    <div className={`kx-kpi kx-kpi--${kpi.trend === 'down' ? 'warn' : 'normal'}`}>
      <span className="kx-kpi__label">{kpi.label}</span>
      <strong className="kx-kpi__value tnum">{kpi.value}</strong>
      {kpi.delta && (
        <span className={`kx-delta kx-delta--${dir}`}>
          {kpi.trend === 'down' ? '▼' : kpi.trend === 'up' ? '▲' : ''} {kpi.delta}
        </span>
      )}
    </div>
  );
}

type GradeKey = 'excellent' | 'good' | 'fair' | 'review';
const GRADE_MAP: Record<string, { key: GradeKey; label: string }> = {
  A: { key: 'excellent', label: 'A' },
  B: { key: 'good', label: 'B' },
  C: { key: 'fair', label: 'C' },
};
function GradePill({ grade }: { grade: string }) {
  const g = GRADE_MAP[grade] ?? { key: 'review' as GradeKey, label: grade };
  return <span className={`kx-grade kx-grade--${g.key}`}>{g.label}</span>;
}

/** 원 금액 → 억/만 단위 축약. */
function formatWon(v: number): string {
  if (v >= 1e8) return `₩${(v / 1e8).toFixed(2)}억`;
  if (v >= 1e4) return `₩${Math.round(v / 1e4).toLocaleString()}만`;
  return `₩${v.toLocaleString()}`;
}
function shortWon(v: number): string {
  if (v >= 1e8) return `${(v / 1e8).toFixed(0)}억`;
  if (v >= 1e4) return `${Math.round(v / 1e4)}만`;
  return String(v);
}

function isDegradable(error: unknown): boolean {
  return (
    error instanceof ApiRequestError &&
    (error.code === 'NETWORK' || error.code === 'NOT_FOUND' || error.code === 'NOT_IMPLEMENTED')
  );
}

/**
 * 샘플 폴백(백엔드 shape 매핑) — 정상 경로는 실 API. NETWORK/NOT_FOUND 시에만 사용.
 * 근거: 기존 sampleAnalytics.ts(BI 데이터마트 미구축 시연 데이터)를 AnalyticsData 로 강등 변환.
 */
function fallback(perspective: AnalyticsPerspective): AnalyticsData {
  const isOperator = perspective === 'operator';
  const kpis = (isOperator ? OPERATOR_KPIS : EXHIBITOR_KPIS).map((k) => ({
    label: k.label,
    value: k.value,
    delta: k.delta ?? null,
    trend: k.deltaDir === 'down' ? 'down' : k.deltaDir === 'up' ? 'up' : 'flat',
  }));
  return {
    kpis,
    trend: [],
    sectors: SECTORS.map((s) => ({ name: s.label, sharePercent: s.pct, revenue: 0 })),
    pnl: isOperator
      ? OPERATOR_PNL.map((r) => ({
          item: `${r.event} (${r.hall})`,
          amount: parseWon(r.revenue),
          grade: r.grade === 'excellent' ? 'A' : r.grade === 'good' ? 'B' : r.grade === 'fair' ? 'C' : 'C',
        }))
      : [],
    exhibitorPerf: isOperator
      ? []
      : EXHIBITOR_PERF.map((r) => ({
          companyName: r.company,
          leads: r.matches,
          conversionPercent: r.visits > 0 ? (r.matches / r.visits) * 100 : 0,
        })),
  };
}
/** "₩412M" 류 표시 문자열 → 원 단위 근사(폴백 전용). */
function parseWon(s: string): number {
  const n = parseFloat(s.replace(/[^0-9.]/g, ''));
  if (Number.isNaN(n)) return 0;
  if (/B/i.test(s)) return Math.round(n * 1e9);
  if (/M/i.test(s)) return Math.round(n * 1e6);
  return Math.round(n);
}
