import { useState } from 'react';
import {
  Drawer, Form, Input, Modal, Space, Tag, Typography, message,
} from 'antd';
import { FileExcelOutlined } from '@ant-design/icons';
import { ProCard } from '@ant-design/pro-components';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import type { ColDef, ICellRendererParams } 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 {
  paymentBatchApi,
  PaymentBatchResp,
  PaymentBatchItemResp,
  PaymentBatchStatus,
} from '@/api/paymentBatch';
import {
  GRAY, RADIUS, SHADOW,
  COLOR_PRIMARY, COLOR_SUCCESS, COLOR_WARNING, COLOR_ERROR,
} from '@/theme/tokens';

const { Text } = Typography;

// ── 상수 ──────────────────────────────────────────────────────────────────
const MENU_CODE = 'PAYMENT_TARGET';

const STATUS_META: Record<
  PaymentBatchStatus,
  { label: string; color: string; bg: string; border: string }
> = {
  DRAFT:      { label: '작성중', color: COLOR_WARNING, bg: '#FFF6E6', border: '#F6D08A' },
  FINALIZED:  { label: '확정',   color: COLOR_SUCCESS, bg: '#E8FAF3', border: '#A3E6C8' },
  CANCELLED:  { label: '취소',   color: COLOR_ERROR,   bg: '#FEF0F1', border: '#F9B0B6' },
};

function BatchStatusTag({ status, statusName }: { status: string; statusName?: string }) {
  const meta = STATUS_META[status as PaymentBatchStatus];
  if (!meta) return <Tag>{statusName ?? status}</Tag>;
  return (
    <Tag
      style={{
        color: meta.color,
        background: meta.bg,
        border: `1px solid ${meta.border}`,
        borderRadius: RADIUS.sm,
        fontWeight: 600,
        fontSize: 12,
        margin: 0,
        padding: '0 8px',
        height: 22,
        lineHeight: '20px',
      }}
    >
      {statusName ?? meta.label}
    </Tag>
  );
}

// YYYYMM 유효성
function isValidYYYYMM(v: string): boolean {
  if (!/^\d{6}$/.test(v)) return false;
  const year = parseInt(v.slice(0, 4), 10);
  const month = parseInt(v.slice(4, 6), 10);
  return year >= 2000 && year <= 2099 && month >= 1 && month <= 12;
}

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

const fmtDt = (v?: string) => (v ? dayjs(v).format('YYYY-MM-DD HH:mm') : '-');

// ── 배치 목록 컬럼 ────────────────────────────────────────────────────────
const BATCH_COLS: ColDef<PaymentBatchResp>[] = [
  { field: 'batchName',   headerName: '배치명',   flex: 2, pinned: 'left' },
  { field: 'settleMonth', headerName: '정산월',   width: 110 },
  {
    field: 'status',
    headerName: '상태',
    width: 110,
    cellRenderer: (p: ICellRendererParams<PaymentBatchResp>) =>
      p.data ? (
        <BatchStatusTag status={p.data.status} statusName={p.data.statusName} />
      ) : null,
  },
  {
    field: 'totalCount',
    headerName: '포함건수',
    width: 110,
    type: 'numericColumn',
    valueFormatter: (p) => `${p.value ?? 0}건`,
  },
  {
    field: 'totalPayable',
    headerName: '지급합계',
    flex: 1,
    type: 'numericColumn',
    valueFormatter: (p) => `${fmtMoney(p.value)}원`,
  },
  {
    field: 'finalizedAt',
    headerName: '확정일시',
    width: 150,
    valueFormatter: (p) => fmtDt(p.value as string | undefined),
  },
  {
    field: 'createdAt',
    headerName: '생성일시',
    width: 150,
    valueFormatter: (p) => fmtDt(p.value as string | undefined),
  },
];

// ── 배치 아이템 컬럼 (상세 Drawer) ────────────────────────────────────────
function buildItemCols(
  isDraft: boolean,
  onToggleIncluded: (item: PaymentBatchItemResp) => void,
): ColDef<PaymentBatchItemResp>[] {
  return [
    { field: 'agentName',     headerName: '설계사', width: 130, pinned: 'left' },
    {
      field: 'payableAmount',
      headerName: '지급액',
      flex: 1,
      type: 'numericColumn',
      valueFormatter: (p) => `${fmtMoney(p.value)}원`,
    },
    {
      field: 'included',
      headerName: '포함',
      width: 80,
      cellRenderer: (p: ICellRendererParams<PaymentBatchItemResp>) => {
        if (!p.data) return null;
        const item = p.data;
        if (isDraft) {
          return (
            <input
              type="checkbox"
              checked={item.included}
              style={{ cursor: 'pointer', width: 16, height: 16 }}
              onChange={() => onToggleIncluded(item)}
            />
          );
        }
        return (
          <input
            type="checkbox"
            checked={item.included}
            disabled
            style={{ width: 16, height: 16 }}
          />
        );
      },
    },
    {
      field: 'excludeReason',
      headerName: '제외사유',
      flex: 2,
      valueFormatter: (p) => (p.value as string | undefined) ?? '',
    },
  ];
}

// ── 메인 컴포넌트 ──────────────────────────────────────────────────────────
export default function PaymentTarget() {
  const qc = useQueryClient();

  // 검색 파라미터
  const [searchParams, setSearchParams] = useState<{
    settleMonth?: string;
    status?: string;
  }>({});

  // 상세 Drawer
  const [selectedBatchId, setSelectedBatchId] = useState<number | null>(null);
  const [drawerOpen, setDrawerOpen] = useState(false);

  // 구성 모달
  const [createModalOpen, setCreateModalOpen] = useState(false);
  const [createForm] = Form.useForm();

  // 제외사유 편집 모달
  const [reasonModal, setReasonModal] = useState<{
    open: boolean;
    item?: PaymentBatchItemResp;
    pendingIncluded?: boolean;
  }>({ open: false });
  const [reasonForm] = Form.useForm();

  // ── 목록 조회 ────────────────────────────────────────
  const { data: listData, isLoading: listLoading } = useQuery({
    queryKey: ['payment-batches', searchParams],
    queryFn: () => paymentBatchApi.list({ ...searchParams, pageSize: 200 }),
    retry: false,
  });

  // ── 상세 조회 ────────────────────────────────────────
  const { data: detail, isLoading: detailLoading } = useQuery({
    queryKey: ['payment-batch', selectedBatchId],
    queryFn: () => paymentBatchApi.detail(selectedBatchId!),
    enabled: !!selectedBatchId,
    retry: false,
  });

  // ── 생성 뮤테이션 ────────────────────────────────────
  const createMutation = useMutation({
    mutationFn: paymentBatchApi.create,
    onSuccess: (newId) => {
      message.success('배치가 생성되었습니다');
      qc.invalidateQueries({ queryKey: ['payment-batches'] });
      setCreateModalOpen(false);
      createForm.resetFields();
      setSelectedBatchId(newId);
      setDrawerOpen(true);
    },
  });

  // ── 아이템 업데이트 뮤테이션 ─────────────────────────
  const updateItemMutation = useMutation({
    mutationFn: ({ itemId, included, excludeReason }: {
      itemId: number;
      included: boolean;
      excludeReason?: string;
    }) => paymentBatchApi.updateItem(selectedBatchId!, itemId, { included, excludeReason }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['payment-batch', selectedBatchId] });
      qc.invalidateQueries({ queryKey: ['payment-batches'] });
    },
  });

  // ── 확정 뮤테이션 ────────────────────────────────────
  const finalizeMutation = useMutation({
    mutationFn: () => paymentBatchApi.finalize(selectedBatchId!),
    onSuccess: () => {
      message.success('배치가 확정되었습니다');
      qc.invalidateQueries({ queryKey: ['payment-batch', selectedBatchId] });
      qc.invalidateQueries({ queryKey: ['payment-batches'] });
    },
  });

  // ── 취소 뮤테이션 ────────────────────────────────────
  const cancelMutation = useMutation({
    mutationFn: () => paymentBatchApi.cancel(selectedBatchId!),
    onSuccess: () => {
      message.success('배치가 취소되었습니다');
      qc.invalidateQueries({ queryKey: ['payment-batch', selectedBatchId] });
      qc.invalidateQueries({ queryKey: ['payment-batches'] });
    },
  });

  // ── 엑셀 다운로드 ────────────────────────────────────
  const handleExport = async () => {
    if (!selectedBatchId) return;
    try {
      const res = await paymentBatchApi.export(selectedBatchId);
      const url = URL.createObjectURL(new Blob([res.data as BlobPart]));
      const a = document.createElement('a');
      a.href = url;
      a.download = `지급대상_${detail?.settleMonth ?? ''}_${dayjs().format('YYYYMMDD')}.xlsx`;
      a.click();
      URL.revokeObjectURL(url);
    } catch {
      /* request.ts 에서 처리 */
    }
  };

  // ── 포함 체크박스 토글 핸들러 ────────────────────────
  const handleToggleIncluded = (item: PaymentBatchItemResp) => {
    // 포함 → 제외 전환 시 사유 입력 모달 표시
    if (item.included) {
      reasonForm.setFieldsValue({ excludeReason: item.excludeReason ?? '' });
      setReasonModal({ open: true, item, pendingIncluded: false });
    } else {
      // 제외 → 포함 전환은 사유 없이 바로 처리
      updateItemMutation.mutate({
        itemId: item.itemId,
        included: true,
        excludeReason: undefined,
      });
    }
  };

  const handleReasonSubmit = async () => {
    if (!reasonModal.item) return;
    const values = await reasonForm.validateFields();
    updateItemMutation.mutate({
      itemId: reasonModal.item.itemId,
      included: false,
      excludeReason: values.excludeReason || undefined,
    });
    setReasonModal({ open: false });
    reasonForm.resetFields();
  };

  const handleCreateSubmit = async () => {
    const values = await createForm.validateFields();
    createMutation.mutate({
      settleMonth: values.settleMonth,
      batchName: values.batchName,
    });
  };

  const rows = listData?.list ?? [];
  const isDraft = detail?.status === 'DRAFT';

  // 합계행
  const batchPinnedBottom =
    rows.length > 0
      ? ({
          batchName: '합계',
          totalCount: rows.reduce((s, r) => s + (r.totalCount ?? 0), 0),
          totalPayable: rows.reduce((s, r) => s + (r.totalPayable ?? 0), 0),
        } as Partial<PaymentBatchResp>)
      : undefined;

  const items = detail?.items ?? [];
  const itemPinnedBottom =
    items.length > 0
      ? ({
          agentName: '합계',
          payableAmount: items
            .filter((i) => i.included)
            .reduce((s, i) => s + (i.payableAmount ?? 0), 0),
        } as Partial<PaymentBatchItemResp>)
      : undefined;

  const itemCols = buildItemCols(isDraft, handleToggleIncluded);

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

  return (
    <PageContainer
      title="지급대상 관리"
      description="정산월 지급대상 배치 구성 · 편집 · 확정"
    >
      {/* ── 검색 폼 ─────────────────────────────────── */}
      <SearchForm
        conditions={[
          { type: 'month', name: 'settleMonth', label: '정산월', span: 6 },
          {
            type: 'code',
            name: 'status',
            label: '상태',
            span: 6,
            groupCode: 'PAYMENT_BATCH_STATUS',
          },
        ]}
        onSearch={(v) => setSearchParams(v as { settleMonth?: string; status?: string })}
        onReset={() => setSearchParams({})}
      />

      {/* ── 배치 목록 그리드 ─────────────────────────── */}
      <ProCard
        style={cardStyle}
        extra={
          <PermissionButton
            menuCode={MENU_CODE}
            permCode="CREATE"
            type="primary"
            onClick={() => {
              createForm.resetFields();
              setCreateModalOpen(true);
            }}
          >
            + 구성
          </PermissionButton>
        }
        title={
          <Text style={{ fontWeight: 600, color: GRAY[700], fontSize: 15 }}>
            배치 목록
          </Text>
        }
      >
        <DataGrid<PaymentBatchResp>
          rows={rows}
          columns={BATCH_COLS}
          loading={listLoading}
          height={400}
          rowKey="batchId"
          pinnedBottomRow={batchPinnedBottom}
          onSelectionChanged={(e) => {
            const sel = e.api.getSelectedRows();
            if (sel.length > 0) {
              setSelectedBatchId(sel[0].batchId);
              setDrawerOpen(true);
            }
          }}
        />
      </ProCard>

      {/* ── 상세 Drawer ──────────────────────────────── */}
      <Drawer
        title={
          detail
            ? `${detail.settleMonth} — ${detail.batchName}`
            : '배치 상세'
        }
        width={760}
        open={drawerOpen}
        onClose={() => setDrawerOpen(false)}
        extra={
          <Space>
            <PermissionButton
              menuCode={MENU_CODE}
              permCode="READ"
              icon={<FileExcelOutlined />}
              onClick={handleExport}
              disabled={!detail}
            >
              엑셀
            </PermissionButton>
            <PermissionButton
              menuCode={MENU_CODE}
              permCode="UPDATE"
              danger
              disabled={!detail || detail.status === 'CANCELLED'}
              loading={cancelMutation.isPending}
              onClick={() => {
                Modal.confirm({
                  title: '배치를 취소하시겠습니까?',
                  okText: '취소 처리',
                  okType: 'danger',
                  cancelText: '닫기',
                  onOk: () => cancelMutation.mutateAsync(),
                });
              }}
            >
              취소
            </PermissionButton>
            <PermissionButton
              menuCode={MENU_CODE}
              permCode="EXECUTE"
              type="primary"
              disabled={!detail || !isDraft}
              loading={finalizeMutation.isPending}
              onClick={() => {
                Modal.confirm({
                  title: '배치를 확정하시겠습니까?',
                  content: '확정 후에는 포함 항목을 수정할 수 없습니다.',
                  okText: '확정',
                  cancelText: '취소',
                  onOk: () => finalizeMutation.mutateAsync(),
                });
              }}
            >
              확정
            </PermissionButton>
          </Space>
        }
      >
        {/* 배치 헤더 요약 */}
        {detail && (
          <div
            style={{
              display: 'grid',
              gridTemplateColumns: 'repeat(3, 1fr)',
              gap: 12,
              marginBottom: 16,
              padding: '12px 16px',
              background: GRAY[50],
              borderRadius: RADIUS.md,
              border: `1px solid ${GRAY[100]}`,
            }}
          >
            <HeaderStat label="상태" value={<BatchStatusTag status={detail.status} statusName={detail.statusName} />} />
            <HeaderStat label="포함건수" value={`${detail.totalCount.toLocaleString()}건`} />
            <HeaderStat label="지급합계" value={`${fmtMoney(detail.totalPayable)}원`} />
          </div>
        )}

        {/* 아이템 그리드 */}
        {detailLoading ? (
          <Text style={{ color: GRAY[400] }}>불러오는 중...</Text>
        ) : (
          <DataGrid<PaymentBatchItemResp>
            rows={items}
            columns={itemCols}
            loading={detailLoading}
            height={500}
            rowKey="itemId"
            pinnedBottomRow={itemPinnedBottom}
          />
        )}

        {/* DRAFT 안내 */}
        {isDraft && (
          <Text
            style={{
              display: 'block',
              marginTop: 8,
              fontSize: 12,
              color: GRAY[500],
            }}
          >
            체크박스를 클릭하여 포함/제외를 변경할 수 있습니다.
          </Text>
        )}
      </Drawer>

      {/* ── 배치 구성 모달 ────────────────────────────── */}
      <Modal
        title="지급대상 배치 구성"
        open={createModalOpen}
        onOk={handleCreateSubmit}
        onCancel={() => { setCreateModalOpen(false); createForm.resetFields(); }}
        okText="구성"
        cancelText="취소"
        confirmLoading={createMutation.isPending}
        destroyOnClose
      >
        <Form form={createForm} layout="vertical" style={{ marginTop: 16 }}>
          <Form.Item
            name="settleMonth"
            label="정산월"
            rules={[
              { required: true, message: '정산월을 입력하세요' },
              {
                validator: (_, v) =>
                  !v || isValidYYYYMM(v)
                    ? Promise.resolve()
                    : Promise.reject(new Error('YYYYMM 6자리로 입력하세요 (예: 202501)')),
              },
            ]}
          >
            <Input placeholder="예: 202501" maxLength={6} style={{ width: 180 }} />
          </Form.Item>
          <Form.Item
            name="batchName"
            label="배치명"
            rules={[{ required: true, message: '배치명을 입력하세요' }]}
          >
            <Input placeholder="예: 2025년 01월 지급대상" maxLength={100} />
          </Form.Item>
        </Form>
      </Modal>

      {/* ── 제외사유 입력 모달 ────────────────────────── */}
      <Modal
        title="제외 처리"
        open={reasonModal.open}
        onOk={handleReasonSubmit}
        onCancel={() => { setReasonModal({ open: false }); reasonForm.resetFields(); }}
        okText="제외"
        okType="danger"
        cancelText="취소"
        confirmLoading={updateItemMutation.isPending}
        destroyOnClose
      >
        <div style={{ marginBottom: 12, color: GRAY[600], fontSize: 13 }}>
          설계사: <strong>{reasonModal.item?.agentName}</strong>
        </div>
        <Form form={reasonForm} layout="vertical">
          <Form.Item name="excludeReason" label="제외사유">
            <Input.TextArea rows={3} placeholder="제외사유를 입력하세요 (선택)" maxLength={300} showCount />
          </Form.Item>
        </Form>
      </Modal>
    </PageContainer>
  );
}

// ── 헤더 요약 아이템 ──────────────────────────────────────────────────────
function HeaderStat({ label, value }: { label: string; value: React.ReactNode }) {
  return (
    <div>
      <Text style={{ fontSize: 12, color: GRAY[500], display: 'block' }}>{label}</Text>
      <Text style={{ fontSize: 14, fontWeight: 600, color: GRAY[800] }}>{value}</Text>
    </div>
  );
}
