import { useRef, useState } from 'react';
import {
  Alert, Button, DatePicker, Space, Table, Tag, Typography, message,
} from 'antd';
import { ProCard } from '@ant-design/pro-components';
import { useQuery, useMutation, 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 {
  chargebackApi,
  ChargebackRow,
  ChargebackSearchParam,
} from '@/api/chargeback';
import { GRAY, RADIUS, SHADOW, COLOR_SUCCESS, COLOR_ERROR, COLOR_WARNING, COLOR_PRIMARY } from '@/theme/tokens';

const { Text } = Typography;

const MENU_CODE = 'CHARGEBACK_DATA';

const STATUS_COLOR: Record<string, string> = {
  NEW:        COLOR_PRIMARY,
  PROCESSING: COLOR_WARNING,
  SETTLED:    COLOR_SUCCESS,
  CANCELLED:  COLOR_ERROR,
};

const STATUS_LABEL: Record<string, string> = {
  NEW:        '신규',
  PROCESSING: '처리중',
  SETTLED:    '정산완료',
  CANCELLED:  '취소',
};

function StatusChip({ status }: { status: string }) {
  const color = STATUS_COLOR[status] ?? GRAY[400];
  const label = STATUS_LABEL[status] ?? status;
  return (
    <Tag
      style={{
        color,
        background: `${color}1A`,
        border: `1px solid ${color}40`,
        borderRadius: RADIUS.sm,
        fontWeight: 600,
        fontSize: 12,
      }}
    >
      {label}
    </Tag>
  );
}

const fmt = (v: unknown) =>
  typeof v === 'number' ? v.toLocaleString() : (v as string | undefined) ?? '-';

const GRID_COLS: ColDef<ChargebackRow>[] = [
  { field: 'policyNo',       headerName: '증권번호',  width: 150, pinned: 'left' },
  { field: 'agentName',      headerName: '설계사',    width: 120 },
  { field: 'contractorName', headerName: '계약자',    width: 120 },
  {
    field: 'cbAmount',
    headerName: '환수금액',
    flex: 1,
    type: 'numericColumn',
    valueFormatter: (p) => fmt(p.value),
  },
  {
    field: 'paidAmount',
    headerName: '기지급',
    flex: 1,
    type: 'numericColumn',
    valueFormatter: (p) => fmt(p.value),
  },
  {
    field: 'remainAmount',
    headerName: '잔여',
    flex: 1,
    type: 'numericColumn',
    valueFormatter: (p) => fmt(p.value),
  },
  { field: 'lapseMonth',  headerName: '경과월',   width: 100 },
  {
    field: 'status',
    headerName: '상태',
    width: 120,
    cellRenderer: (p: { data: ChargebackRow }) =>
      p.data ? <StatusChip status={p.data.status} /> : null,
  },
  { field: 'settleMonth', headerName: '정산월',   width: 110 },
];

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

export default function ChargebackData() {
  const qc = useQueryClient();

  // ── 업로드 상태 ──────────────────────────────────
  const [uploadMonth, setUploadMonth] = useState<string>('');
  const [uploadFile, setUploadFile]   = useState<File | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);

  // ── 목록 검색 파라미터 ───────────────────────────
  const [params, setParams] = useState<ChargebackSearchParam>({ pageSize: 500 });

  // ── 목록 조회 ──────────────────────────────────
  const { data: listData, isLoading } = useQuery({
    queryKey: ['chargebacks', params],
    queryFn: () => chargebackApi.list(params),
    retry: false,
  });

  // ── 업로드 뮤테이션 ──────────────────────────────
  const uploadMutation = useMutation({
    mutationFn: ({ month, file }: { month: string; file: File }) =>
      chargebackApi.upload(month, file),
    onSuccess: (result) => {
      const { successCount, skipCount, errorCount } = result;
      if (errorCount === 0) {
        message.success(`업로드 완료 — 성공 ${successCount}건, 스킵 ${skipCount}건`);
      } else {
        message.warning(`업로드 완료 — 성공 ${successCount}건, 스킵 ${skipCount}건, 오류 ${errorCount}건`);
      }
      qc.invalidateQueries({ queryKey: ['chargebacks'] });
      // 파일 입력 초기화
      setUploadFile(null);
      if (fileInputRef.current) fileInputRef.current.value = '';
    },
  });

  const uploadResult = uploadMutation.data;

  const handleUpload = () => {
    if (!uploadMonth) {
      message.error('정산월을 입력하세요');
      return;
    }
    if (!uploadFile) {
      message.error('파일을 선택하세요');
      return;
    }
    uploadMutation.mutate({ month: uploadMonth, file: uploadFile });
  };

  const handleExport = async () => {
    try {
      const res = await chargebackApi.export(params);
      const url = URL.createObjectURL(new Blob([res.data as BlobPart]));
      const a = document.createElement('a');
      a.href = url;
      a.download = `환수자료_${dayjs().format('YYYYMMDD')}.xlsx`;
      a.click();
      URL.revokeObjectURL(url);
    } catch {
      /* request.ts 처리 */
    }
  };

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

  const pinnedBottom =
    rows.length > 0
      ? ({
          policyNo:    '합계',
          cbAmount:    rows.reduce((s, r) => s + (r.cbAmount ?? 0), 0),
          remainAmount: rows.reduce((s, r) => s + (r.remainAmount ?? 0), 0),
        } as Partial<ChargebackRow>)
      : undefined;

  return (
    <PageContainer
      title="환수자료관리"
      description="보험사 환수 자료 업로드 및 환수 목록 조회"
      extra={
        <PermissionButton menuCode={MENU_CODE} permCode="EXPORT" onClick={handleExport}>
          엑셀 다운로드
        </PermissionButton>
      }
    >
      {/* ── 업로드 영역 ────────────────────────────── */}
      <ProCard
        title="보험사 환수자료 업로드"
        style={{ ...cardStyle, marginBottom: 16 }}
        bodyStyle={{ padding: '16px 20px' }}
      >
        <Space wrap size={12} align="end">
          <div>
            <Text style={{ fontSize: 12, color: GRAY[600], display: 'block', marginBottom: 4 }}>
              정산월
            </Text>
            <DatePicker
              picker="month"
              style={{ width: 150 }}
              onChange={(_, val) => setUploadMonth(Array.isArray(val) ? val[0] : val)}
              format="YYYYMM"
            />
          </div>

          <div>
            <Text style={{ fontSize: 12, color: GRAY[600], display: 'block', marginBottom: 4 }}>
              파일 선택 (xlsx/xls)
            </Text>
            <Space size={8}>
              <Button onClick={() => fileInputRef.current?.click()}>
                {uploadFile ? uploadFile.name : '파일 선택'}
              </Button>
              <input
                ref={fileInputRef}
                type="file"
                accept=".xlsx,.xls"
                style={{ display: 'none' }}
                onChange={(e) => {
                  setUploadFile(e.target.files?.[0] ?? null);
                }}
              />
            </Space>
          </div>

          <PermissionButton
            menuCode={MENU_CODE}
            permCode="CREATE"
            type="primary"
            loading={uploadMutation.isPending}
            onClick={handleUpload}
          >
            업로드
          </PermissionButton>
        </Space>

        {/* ── 업로드 결과 ─────────────────────────── */}
        {uploadResult && (
          <div style={{ marginTop: 16 }}>
            <Space size={24} style={{ marginBottom: 8 }}>
              <Text style={{ color: COLOR_SUCCESS, fontWeight: 600 }}>
                성공 {uploadResult.successCount}건
              </Text>
              <Text style={{ color: GRAY[500], fontWeight: 600 }}>
                스킵 {uploadResult.skipCount}건
              </Text>
              {uploadResult.errorCount > 0 && (
                <Text style={{ color: COLOR_ERROR, fontWeight: 600 }}>
                  오류 {uploadResult.errorCount}건
                </Text>
              )}
            </Space>

            {uploadResult.errors.length > 0 && (
              <Alert
                type="error"
                message={`오류 행 목록 (${uploadResult.errors.length}건)`}
                description={
                  <Table
                    size="small"
                    rowKey="rowNo"
                    dataSource={uploadResult.errors}
                    pagination={false}
                    style={{ marginTop: 8 }}
                    columns={[
                      { title: '행 번호', dataIndex: 'rowNo', width: 80, align: 'right' },
                      { title: '사유',    dataIndex: 'reason' },
                    ]}
                  />
                }
                style={{ marginTop: 4 }}
              />
            )}
          </div>
        )}
      </ProCard>

      {/* ── 검색 폼 ────────────────────────────────── */}
      <SearchForm
        conditions={[
          { type: 'month', name: 'settleMonth', label: '정산월',   span: 6 },
          { type: 'text',  name: 'policyNo',    label: '증권번호', span: 6 },
          { type: 'text',  name: 'status',      label: '상태',     span: 6 },
        ]}
        onSearch={(v) => setParams({ ...(v as ChargebackSearchParam), pageSize: 500 })}
        onReset={() => setParams({ pageSize: 500 })}
      />

      {/* ── AG Grid 목록 ───────────────────────────── */}
      <ProCard style={cardStyle}>
        <DataGrid<ChargebackRow>
          rows={rows}
          columns={GRID_COLS}
          loading={isLoading}
          height={560}
          rowKey="cbId"
          pinnedBottomRow={pinnedBottom}
        />
      </ProCard>
    </PageContainer>
  );
}
