import { useMemo, useState } from 'react';
import { Alert, Button, Col, Row, Space, Typography } from 'antd';
import { ProCard } from '@ant-design/pro-components';
import { useQuery } from '@tanstack/react-query';
import {
  AreaChart, Area, BarChart, Bar, XAxis, YAxis,
  CartesianGrid, Tooltip, ResponsiveContainer, Legend,
} from 'recharts';
import {
  IconTrendingUp, IconTrendingDown, IconMinus, IconDownload,
} from '@tabler/icons-react';
import type { ColDef } from '@ag-grid-community/core';
import dayjs from 'dayjs';
import PageContainer from '@/components/common/PageContainer';
import SearchForm from '@/components/common/SearchForm';
import DataGrid from '@/components/common/DataGrid';
import { kpiApi, MonthlySummaryRow, KpiSearchParam } from '@/api/kpi';
import {
  COLOR_PRIMARY, COLOR_ERROR, COLOR_SUCCESS,
  GRAY, SHADOW, RADIUS,
} from '@/theme/tokens';

const { Text } = Typography;

// ────────────────────────────────────────────────────────
// 유틸
// ────────────────────────────────────────────────────────

const fmt = (v: number) => v.toLocaleString();
const fmtM = (v: number) => `${(v / 1_000_000).toFixed(1)}M`;

function calcPct(curr: number, prev: number): number | null {
  if (prev === 0) return null;
  return Math.round(((curr - prev) / Math.abs(prev)) * 1000) / 10;
}

// ────────────────────────────────────────────────────────
// 서브 컴포넌트 — KPI 카드
// ────────────────────────────────────────────────────────

interface KpiCardProps {
  label: string;
  value: number;
  unit?: string;
  delta?: number | null;
  deltaLabel?: string;
  color?: string;
  bg?: string;
}

function KpiCard({ label, value, unit = '원', delta, deltaLabel, color = COLOR_PRIMARY, bg = '#EBF3FF' }: KpiCardProps) {
  const renderDelta = () => {
    if (delta === null || delta === undefined) return null;
    if (delta > 0) return (
      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 2, fontSize: 12, fontWeight: 600, color: COLOR_SUCCESS }}>
        <IconTrendingUp size={12} />+{delta.toFixed(1)}%
      </span>
    );
    if (delta < 0) return (
      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 2, fontSize: 12, fontWeight: 600, color: COLOR_ERROR }}>
        <IconTrendingDown size={12} />{delta.toFixed(1)}%
      </span>
    );
    return (
      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 2, fontSize: 12, color: GRAY[400] }}>
        <IconMinus size={12} />변동없음
      </span>
    );
  };

  return (
    <div style={{
      background: '#ffffff',
      borderRadius: RADIUS.lg,
      border: `1px solid ${GRAY[100]}`,
      boxShadow: SHADOW.sm,
      padding: '24px 28px',
      display: 'flex',
      flexDirection: 'column',
      gap: 12,
    }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <Text style={{ fontSize: 13, fontWeight: 500, color: GRAY[500] }}>{label}</Text>
        <div style={{
          width: 36, height: 36, borderRadius: 10,
          background: bg, color,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <IconTrendingUp size={18} />
        </div>
      </div>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>
        <span style={{
          fontSize: 34, fontWeight: 700, color: GRAY[800], lineHeight: 1,
          fontFeatureSettings: "'tnum'", fontVariantNumeric: 'tabular-nums',
        }}>
          {fmtM(value)}
        </span>
        <Text style={{ fontSize: 14, color: GRAY[500] }}>{unit}</Text>
      </div>
      {(delta !== null && delta !== undefined) && (
        <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
          {renderDelta()}
          {deltaLabel && <Text style={{ fontSize: 12, color: GRAY[400] }}>{deltaLabel}</Text>}
        </div>
      )}
    </div>
  );
}

// ────────────────────────────────────────────────────────
// AG Grid 컬럼 정의
// ────────────────────────────────────────────────────────

const COLUMNS: ColDef<MonthlySummaryRow>[] = [
  { field: 'yyyymm',        headerName: '정산월',     width: 110, pinned: 'left' },
  { field: 'agentCount',    headerName: '설계사수',   width: 100, type: 'numericColumn', valueFormatter: (p) => fmt(p.value ?? 0) },
  { field: 'totalGross',    headerName: '총수수료',   flex: 1,    type: 'numericColumn', valueFormatter: (p) => fmt(p.value ?? 0) },
  { field: 'totalTax',      headerName: '총공제(세)', flex: 1,    type: 'numericColumn', valueFormatter: (p) => fmt(p.value ?? 0) },
  { field: 'totalNet',      headerName: '총지급',     flex: 1,    type: 'numericColumn', valueFormatter: (p) => fmt(p.value ?? 0) },
  { field: 'totalChargeback', headerName: '환수',     flex: 1,    type: 'numericColumn', valueFormatter: (p) => fmt(p.value ?? 0) },
  { field: 'totalIncentive',  headerName: '시책',     flex: 1,    type: 'numericColumn', valueFormatter: (p) => fmt(p.value ?? 0) },
];

// ────────────────────────────────────────────────────────
// 클라이언트 사이드 엑셀 내보내기 (xlsx 없음 — CSV 대체)
// ────────────────────────────────────────────────────────

function exportCsv(rows: MonthlySummaryRow[]) {
  const headers = ['정산월', '설계사수', '총수수료', '총공제', '총지급', '환수', '시책'];
  const lines = [
    headers.join(','),
    ...rows.map((r) =>
      [r.yyyymm, r.agentCount, r.totalGross, r.totalTax, r.totalNet, r.totalChargeback, r.totalIncentive].join(','),
    ),
  ];
  const blob = new Blob(['﻿' + lines.join('\n')], { type: 'text/csv;charset=utf-8;' });
  const link = document.createElement('a');
  link.href = URL.createObjectURL(blob);
  link.download = `월별정산요약_${dayjs().format('YYYYMMDD')}.csv`;
  link.click();
  URL.revokeObjectURL(link.href);
}

// ────────────────────────────────────────────────────────
// 메인 컴포넌트
// ────────────────────────────────────────────────────────

export default function KpiMonthlySummary() {
  const [params, setParams] = useState<KpiSearchParam>({
    fromMonth: dayjs().subtract(11, 'month').format('YYYYMM'),
    toMonth: dayjs().format('YYYYMM'),
    pageSize: 100,
  });

  const { data, isLoading, isError } = useQuery({
    queryKey: ['kpi', 'monthly', params],
    queryFn: () => kpiApi.monthlySummary(params),
    retry: false,
  });

  const rows = data?.list ?? [];

  // KPI 카드: 최신월 / 전월 / YTD 합산
  const thisMonth = rows[rows.length - 1];
  const prevMonth = rows.length >= 2 ? rows[rows.length - 2] : undefined;
  const ytdGross = rows.reduce((s, r) => s + (r.totalGross ?? 0), 0);
  const grossDelta = thisMonth && prevMonth
    ? calcPct(thisMonth.totalGross, prevMonth.totalGross)
    : null;

  // 합계행
  const pinnedRow = rows.length > 0 ? {
    yyyymm: '합계',
    agentCount: rows.reduce((s, r) => s + r.agentCount, 0),
    totalGross: rows.reduce((s, r) => s + r.totalGross, 0),
    totalTax: rows.reduce((s, r) => s + r.totalTax, 0),
    totalNet: rows.reduce((s, r) => s + r.totalNet, 0),
    totalChargeback: rows.reduce((s, r) => s + r.totalChargeback, 0),
    totalIncentive: rows.reduce((s, r) => s + r.totalIncentive, 0),
  } as Partial<MonthlySummaryRow> : undefined;

  // 차트 데이터 — 최근 12개월
  const chartData = useMemo(() =>
    rows.slice(-12).map((r) => ({
      month: r.yyyymm.slice(4, 6) + '월',
      총수수료: Math.round(r.totalGross / 1_000_000),
      총지급: Math.round(r.totalNet / 1_000_000),
      환수: Math.round(r.totalChargeback / 1_000_000),
    })),
  [rows]);

  const handleSearch = (values: Record<string, unknown>) => {
    setParams({
      fromMonth: values.fromMonth as string | undefined,
      toMonth: values.toMonth as string | undefined,
      pageSize: 100,
    });
  };

  return (
    <PageContainer
      title="월별 정산 요약"
      description="정산월별 수수료 / 공제 / 지급 합계 — Materialized View"
      extra={
        <Button
          icon={<IconDownload size={14} />}
          onClick={() => rows.length && exportCsv(rows)}
          disabled={!rows.length}
          style={{ display: 'flex', alignItems: 'center', gap: 4 }}
        >
          CSV 다운로드
        </Button>
      }
    >
      {/* 검색 */}
      <SearchForm
        conditions={[
          { type: 'month', name: 'fromMonth', label: '시작 월', span: 6 },
          { type: 'month', name: 'toMonth',   label: '종료 월', span: 6 },
        ]}
        onSearch={handleSearch}
        onReset={() => setParams({ fromMonth: dayjs().subtract(11, 'month').format('YYYYMM'), toMonth: dayjs().format('YYYYMM'), pageSize: 100 })}
      />

      {isError && (
        <Alert type="warning" showIcon
          message="API 미응답"
          description="/api/kpi/monthly-summary 를 확인하세요."
          style={{ marginBottom: 16 }}
        />
      )}

      {/* KPI 카드 3개 */}
      <Row gutter={20} style={{ marginBottom: 20 }}>
        <Col span={8}>
          <KpiCard
            label="당월 총수수료"
            value={thisMonth?.totalGross ?? 0}
            unit="원"
            delta={grossDelta}
            deltaLabel="전월比"
            color={COLOR_PRIMARY}
            bg="#EBF3FF"
          />
        </Col>
        <Col span={8}>
          <KpiCard
            label="당월 총지급"
            value={thisMonth?.totalNet ?? 0}
            unit="원"
            color={COLOR_SUCCESS}
            bg="#E8FAF3"
          />
        </Col>
        <Col span={8}>
          <KpiCard
            label={`YTD 누계 (${dayjs().format('YYYY')})`}
            value={ytdGross}
            unit="원"
            color="#7C3AED"
            bg="#F3EEFF"
          />
        </Col>
      </Row>

      {/* 차트 */}
      <ProCard
        title={<span style={{ fontSize: 15, fontWeight: 700, color: GRAY[800] }}>최근 12개월 수수료 추이</span>}
        subTitle={<span style={{ fontSize: 13, color: GRAY[400] }}>단위: 백만원</span>}
        headerBordered
        style={{
          background: '#ffffff', borderRadius: RADIUS.lg,
          border: `1px solid ${GRAY[100]}`, boxShadow: SHADOW.sm,
          marginBottom: 20,
        }}
      >
        <ResponsiveContainer width="100%" height={260}>
          {chartData.length > 0 ? (
            <BarChart data={chartData} margin={{ top: 8, right: 16, left: -8, bottom: 0 }}>
              <CartesianGrid strokeDasharray="3 3" stroke={GRAY[100]} vertical={false} />
              <XAxis dataKey="month" tick={{ fontSize: 12, fill: GRAY[500] }} axisLine={false} tickLine={false} />
              <YAxis tick={{ fontSize: 12, fill: GRAY[500] }} axisLine={false} tickLine={false} />
              <Tooltip
                contentStyle={{ borderRadius: 12, border: `1px solid ${GRAY[100]}`, boxShadow: SHADOW.md, fontSize: 13 }}
                formatter={(v: number) => [`${v}백만`, '']}
              />
              <Legend wrapperStyle={{ fontSize: 12, paddingTop: 8 }} />
              <Bar dataKey="총수수료" fill={COLOR_PRIMARY} radius={[4, 4, 0, 0]} />
              <Bar dataKey="총지급"   fill={COLOR_SUCCESS} radius={[4, 4, 0, 0]} />
              <Bar dataKey="환수"     fill={COLOR_ERROR}   radius={[4, 4, 0, 0]} />
            </BarChart>
          ) : (
            <AreaChart data={[]} margin={{ top: 8, right: 16, left: -8, bottom: 0 }}>
              <XAxis /><YAxis />
            </AreaChart>
          )}
        </ResponsiveContainer>
      </ProCard>

      {/* AG Grid */}
      <ProCard
        style={{
          background: '#ffffff', borderRadius: RADIUS.lg,
          border: `1px solid ${GRAY[100]}`, boxShadow: SHADOW.sm,
        }}
      >
        <DataGrid<MonthlySummaryRow>
          rows={rows}
          columns={COLUMNS}
          loading={isLoading}
          height={480}
          pinnedBottomRow={pinnedRow}
        />
      </ProCard>
    </PageContainer>
  );
}
