import { useState } from 'react';
import { Alert, Form, Input, Modal, Select, message } from 'antd';
import { ProCard } from '@ant-design/pro-components';
import { useQuery, useQueryClient } from '@tanstack/react-query';
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 PermissionButton from '@/components/common/PermissionButton';
import {
  forecastKpiApi,
  ForecastKpiResp,
  ForecastKpiSearchParam,
} from '@/api/forecast-kpi';
import { GRAY, RADIUS, SHADOW } from '@/theme/tokens';

const fmt = (v: unknown) => (v == null ? '-' : (v as number).toLocaleString());

const COLUMNS: ColDef<ForecastKpiResp>[] = [
  { field: 'forecastMonth', headerName: '예측월',   width: 110, pinned: 'left' },
  { field: 'targetOrgName', headerName: '대상조직', width: 150, valueFormatter: (p) => (p.value as string) ?? '전사' },
  { field: 'metricName',    headerName: '지표',     width: 160 },
  { field: 'forecastValue', headerName: '예측값',   flex: 1, type: 'numericColumn', valueFormatter: (p) => fmt(p.value) },
  { field: 'lowerBound',    headerName: '하한(-1σ)', flex: 1, type: 'numericColumn', valueFormatter: (p) => fmt(p.value) },
  { field: 'upperBound',    headerName: '상한(+1σ)', flex: 1, type: 'numericColumn', valueFormatter: (p) => fmt(p.value) },
  { field: 'methodName',    headerName: '예측기법', width: 130 },
  { field: 'basePeriod',    headerName: '산출기준', width: 180 },
  { field: 'sampleCount',   headerName: '표본수',   width: 90, type: 'numericColumn' },
  { field: 'generatedAt',   headerName: '산출일시', width: 150 },
];

const cardStyle = { background: '#fff', borderRadius: RADIUS.lg, border: `1px solid ${GRAY[100]}`, boxShadow: SHADOW.sm };

export default function ForecastKpiList() {
  const qc = useQueryClient();
  const nextMonth = dayjs().add(1, 'month').format('YYYY-MM');
  const [params, setParams] = useState<ForecastKpiSearchParam>({ pageSize: 200 });
  const [regenOpen, setRegenOpen] = useState(false);
  const [regenForm] = Form.useForm();

  const { data, isLoading, isError } = useQuery({
    queryKey: ['forecast-kpi', params],
    queryFn: () => forecastKpiApi.list(params),
    retry: false,
  });

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

  const handleRegenerate = async () => {
    const values = await regenForm.validateFields();
    try {
      const affected = await forecastKpiApi.regenerate(values);
      message.success(`차월 예측 재산출 완료 (${affected}건)`);
      qc.invalidateQueries({ queryKey: ['forecast-kpi'] });
      setRegenOpen(false);
      regenForm.resetFields();
    } catch { /* request.ts 처리 */ }
  };

  return (
    <PageContainer
      title="차월 KPI 예측"
      description="이동평균 기반 차월 보험료/지급/유지율 예측"
      extra={
        <PermissionButton menuCode="FORECAST_KPI" permCode="EXECUTE"
          type="primary" onClick={() => setRegenOpen(true)}>
          재산출
        </PermissionButton>
      }
    >
      {isError && (
        <Alert type="warning" showIcon message="API 미응답"
          description="/api/forecast-kpi 를 확인하세요." style={{ marginBottom: 16 }} />
      )}

      <SearchForm
        conditions={[
          { type: 'text', name: 'forecastMonth', label: '예측월(YYYY-MM)', span: 7 },
          { type: 'text', name: 'metricCode',    label: '지표코드', span: 7 },
        ]}
        onSearch={(v) => setParams({ ...v as ForecastKpiSearchParam, pageSize: 200 })}
        onReset={() => setParams({ pageSize: 200 })}
      />

      <ProCard style={cardStyle}>
        <DataGrid<ForecastKpiResp>
          rows={rows}
          columns={COLUMNS}
          loading={isLoading}
          height={520}
          rowKey="forecastId"
        />
      </ProCard>

      {/* 재산출 */}
      <Modal
        title="차월 KPI 예측 재산출"
        open={regenOpen}
        onOk={handleRegenerate}
        onCancel={() => { setRegenOpen(false); regenForm.resetFields(); }}
        okText="재산출"
        cancelText="취소"
      >
        <Form form={regenForm} layout="vertical"
          initialValues={{ forecastMonth: nextMonth, method: 'SMA3' }} style={{ marginTop: 16 }}>
          <Form.Item name="forecastMonth" label="예측 대상월"
            rules={[{ required: true, message: '예측 대상월을 입력하세요 (YYYY-MM)' }]}>
            <Input placeholder="예: 2025-05" />
          </Form.Item>
          <Form.Item name="method" label="예측 기법">
            <Select
              options={[
                { value: 'SMA3',  label: '3개월 이동평균' },
                { value: 'SMA6',  label: '6개월 이동평균' },
                { value: 'NAIVE', label: '단순 직전월' },
              ]}
            />
          </Form.Item>
        </Form>
      </Modal>
    </PageContainer>
  );
}
