import { useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import {
  Bar,
  BarChart,
  CartesianGrid,
  Line,
  LineChart,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from 'recharts';
import { AiLabel } from '../../components/ui/Badge';
import { EmptyState, Skeleton } from '../../components/ui/States';
import { IconAnalytics, IconGrid, IconSpark, IconTrendUp } from '../../components/ui/icons';
import { CHART } from '../chartColors';
import { ApiRequestError } from '../../api/client';
import {
  analyticsOverviewApi,
  type AnalyticsOverview,
  type ForecastPoint,
} from './analyticsOverviewApi';

/*
 * SCR-13 경영분석 — 테넌트 전역(행사 횡단) 섹션. 홀매니저 전용.
 * 실 API GET /api/analytics/overview?years=N. 권한 없음(FORBIDDEN)·오프라인·미구현이면 섹션 숨김(null).
 * 행사 간 매출 비교 · 홀 가동률 추이(월별) · 참가사 리텐션 · 수요예측(추세, AI 호출 없음).
 */
export function GlobalOverviewSection() {
  const { t } = useTranslation();
  const [years, setYears] = useState(5);
  const q = useQuery({
    queryKey: ['analytics-overview', years],
    queryFn: () => analyticsOverviewApi.get(years),
    retry: false,
  });

  // 권한 없음/오프라인/미구현 → 조용히 숨김(비홀매니저 화면 오염 방지).
  if (q.isError && isHideable(q.error)) return null;

  return (
    <section className="kx-bi__global" aria-label={t('global.sectionAria')}>
      <div className="kx-bi__global-head">
        <div>
          <h2 className="kx-bi__global-title">{t('global.title')}</h2>
          <p className="kx-card__hint">{t('global.subtitle')}</p>
        </div>
        <select
          className="kx-select"
          aria-label={t('global.yearsAria')}
          value={years}
          onChange={(e) => setYears(Number(e.target.value))}
        >
          <option value={3}>{t('global.years3')}</option>
          <option value={5}>{t('global.years5')}</option>
          <option value={10}>{t('global.years10')}</option>
        </select>
      </div>

      {q.isLoading && <Skeleton height={280} radius={12} />}
      {q.isError && !isHideable(q.error) && (
        <EmptyState title={t('global.loadErrorTitle')} description={t('global.loadErrorDesc')} />
      )}

      {q.data && <OverviewBody data={q.data} />}
    </section>
  );
}

function OverviewBody({ data }: { data: AnalyticsOverview }) {
  const { t } = useTranslation();
  return (
    <>
      {/* 전역 KPI 밴드 */}
      <div className="kx-bi__kpis" aria-label={t('global.kpisAria')}>
        {data.kpis.length === 0 ? (
          <EmptyState title={t('global.kpiEmpty')} />
        ) : (
          data.kpis.map((k, i) => (
            <div key={`${k.label}-${i}`} className="kx-kpi kx-kpi--normal">
              <span className="kx-kpi__label">{k.label}</span>
              <strong className="kx-kpi__value tnum">{k.value}</strong>
              {k.hint && <span className="kx-kpi__hint">{k.hint}</span>}
            </div>
          ))
        )}
      </div>

      <div className="kx-bi__split">
        {/* 행사 간 매출 비교 */}
        <section className="kx-card" aria-label={t('global.evComp')}>
          <div className="kx-card__head">
            <h2><IconAnalytics className="kx-title-ic" size={18} />{t('global.evComp')}</h2>
            <AiLabel>{t('global.top8')}</AiLabel>
          </div>
          <p className="kx-card__hint">{t('global.evCompHint')}</p>
          {data.eventComparison.length === 0 ? (
            <EmptyState title={t('global.evCompEmptyTitle')} description={t('global.evCompEmptyDesc')} />
          ) : (
            <div className="kx-bi__chart">
              <ResponsiveContainer width="100%" height={280}>
                <BarChart
                  data={data.eventComparison}
                  layout="vertical"
                  margin={{ top: 8, right: 16, bottom: 0, left: 8 }}
                >
                  <CartesianGrid stroke={CHART.neutral200} strokeDasharray="3 3" horizontal={false} />
                  <XAxis
                    type="number"
                    tick={{ fontSize: 12, fill: CHART.slate }}
                    tickLine={false}
                    axisLine={{ stroke: CHART.neutral200 }}
                    tickFormatter={(v) => shortWon(v as number)}
                  />
                  <YAxis
                    type="category"
                    dataKey="eventName"
                    tick={{ fontSize: 11, fill: CHART.slate }}
                    tickLine={false}
                    axisLine={false}
                    width={120}
                    tickFormatter={(v) => truncate(v as string, 12)}
                  />
                  <Tooltip contentStyle={TOOLTIP_STYLE} formatter={(v) => formatWon(v as number)} />
                  <Bar dataKey="revenue" name={t('global.revenue')} fill={CHART.primary600} radius={[0, 4, 4, 0]} />
                </BarChart>
              </ResponsiveContainer>
            </div>
          )}
        </section>

        {/* 참가사 리텐션 */}
        <section className="kx-card" aria-label={t('global.retention')}>
          <div className="kx-card__head">
            <h2><IconTrendUp className="kx-title-ic" size={18} />{t('global.retention')}</h2>
          </div>
          <p className="kx-card__hint">
            {t('global.retentionCum')}{' '}
            <strong className="tnum">{data.retention.retentionPercent.toFixed(1)}%</strong> (
            {data.retention.returningCompanies.toLocaleString()}/
            {data.retention.totalCompanies.toLocaleString()} {t('global.returning')})
          </p>
          {data.retention.byYear.length === 0 ? (
            <EmptyState title={t('global.retentionEmptyTitle')} description={t('global.retentionEmptyDesc')} />
          ) : (
            <div className="kx-bi__chart">
              <ResponsiveContainer width="100%" height={280}>
                <LineChart data={data.retention.byYear} margin={{ top: 8, right: 16, bottom: 0, left: -8 }}>
                  <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 tick={{ fontSize: 12, fill: CHART.slate }} tickLine={false} axisLine={false} width={40} tickFormatter={(v) => `${v}%`} />
                  <Tooltip contentStyle={TOOLTIP_STYLE} formatter={(v) => `${(v as number).toFixed(1)}%`} />
                  <Line type="monotone" dataKey="retentionPercent" name={t('global.retentionRate')} stroke={CHART.success} strokeWidth={2} dot={{ r: 3 }} />
                </LineChart>
              </ResponsiveContainer>
            </div>
          )}
        </section>
      </div>

      <div className="kx-bi__split">
        {/* 홀 가동률 추이 */}
        <section className="kx-card" aria-label={t('global.occupancy')}>
          <div className="kx-card__head">
            <h2><IconGrid className="kx-title-ic" size={18} />{t('global.occupancy')}</h2>
          </div>
          <p className="kx-card__hint">{t('global.occupancyHint')}</p>
          {data.hallOccupancy.length === 0 ? (
            <EmptyState title={t('global.occupancyEmpty')} />
          ) : (
            <div className="kx-bi__chart">
              <ResponsiveContainer width="100%" height={280}>
                <BarChart data={data.hallOccupancy} margin={{ top: 8, right: 16, bottom: 0, left: -8 }}>
                  <CartesianGrid stroke={CHART.neutral200} strokeDasharray="3 3" vertical={false} />
                  <XAxis dataKey="period" tick={{ fontSize: 11, fill: CHART.slate }} tickLine={false} axisLine={{ stroke: CHART.neutral200 }} />
                  <YAxis tick={{ fontSize: 12, fill: CHART.slate }} tickLine={false} axisLine={false} width={40} tickFormatter={(v) => `${v}%`} />
                  <Tooltip contentStyle={TOOLTIP_STYLE} formatter={(v) => `${(v as number).toFixed(1)}%`} />
                  <Bar dataKey="occupancyPercent" name={t('global.occupancyRate')} fill={CHART.primary600} radius={[4, 4, 0, 0]} />
                </BarChart>
              </ResponsiveContainer>
            </div>
          )}
        </section>

        {/* 수요예측(추세) */}
        <section className="kx-card" aria-label={t('global.forecast')}>
          <div className="kx-card__head">
            <h2><IconSpark className="kx-title-ic" size={18} />{t('global.forecastTitle')}</h2>
            <AiLabel>{t('global.trendProjection')}</AiLabel>
          </div>
          <p className="kx-card__hint">{t('global.forecastHint')}</p>
          <ForecastChart forecast={data.forecast} />
        </section>
      </div>
    </>
  );
}

function ForecastChart({ forecast }: { forecast: AnalyticsOverview['forecast'] }) {
  const { t } = useTranslation();
  const merged = mergeForecast(forecast.history, forecast.projection);
  if (merged.length === 0) {
    return <EmptyState title={t('global.forecastEmptyTitle')} description={t('global.forecastEmptyDesc')} />;
  }
  return (
    <div className="kx-bi__chart">
      <ResponsiveContainer width="100%" height={280}>
        <LineChart data={merged} margin={{ top: 8, right: 16, bottom: 0, left: -8 }}>
          <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 tick={{ fontSize: 12, fill: CHART.slate }} tickLine={false} axisLine={false} width={40} />
          <Tooltip
            contentStyle={TOOLTIP_STYLE}
            formatter={(v, name) => (v == null ? ['-', name as string] : [t('global.casesUnit', { n: Math.round(v as number) }), name as string])}
          />
          <Line type="monotone" dataKey="actual" name={t('global.actual')} stroke={CHART.primary600} strokeWidth={2} dot={{ r: 3 }} connectNulls />
          <Line
            type="monotone"
            dataKey="projected"
            name={t('global.projected')}
            stroke={CHART.aiAccent}
            strokeWidth={2}
            strokeDasharray="5 4"
            dot={{ r: 3 }}
            connectNulls
          />
        </LineChart>
      </ResponsiveContainer>
    </div>
  );
}

interface MergedPoint {
  period: string;
  actual: number | null;
  projected: number | null;
}
/** 실측+예측을 단일 시리즈로 병합. 마지막 실측점을 예측선에 복제해 두 선을 연결한다. */
function mergeForecast(history: ForecastPoint[], projection: ForecastPoint[]): MergedPoint[] {
  const out: MergedPoint[] = history.map((p) => ({ period: p.period, actual: p.value, projected: null }));
  if (out.length > 0 && projection.length > 0) {
    out[out.length - 1].projected = out[out.length - 1].actual; // 브릿지
  }
  for (const p of projection) {
    out.push({ period: p.period, actual: null, projected: p.value });
  }
  return out;
}

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

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 truncate(s: string, n: number): string {
  return s.length > n ? `${s.slice(0, n)}…` : s;
}

/** 숨김 처리 대상 오류(권한 없음·오프라인·미구현) — 비홀매니저/오프라인 시 섹션 무노출. */
function isHideable(error: unknown): boolean {
  return (
    error instanceof ApiRequestError &&
    (error.code === 'FORBIDDEN' ||
      error.code === 'UNAUTHORIZED' ||
      error.code === 'NETWORK' ||
      error.code === 'NOT_FOUND' ||
      error.code === 'NOT_IMPLEMENTED')
  );
}
