import { useRef, useState } from 'react';
import { Modal, Space, message } from 'antd';
import {
  ModalForm,
  ProForm,
  ProFormDigit,
  ProFormSelect,
  ProFormText,
  ProTable,
  type ActionType,
  type ProColumns,
} from '@ant-design/pro-components';
import dayjs from 'dayjs';
import PageContainer from '@/components/common/PageContainer';
import CodeBadge from '@/components/common/CodeBadge';
import MoneyText from '@/components/common/MoneyText';
import PermissionButton from '@/components/common/PermissionButton';
import { useCommonCodes } from '@/hooks/useCommonCodes';
import {
  deductionApi,
  DeductionResp,
  DeductionSaveReq,
  DeductionSearchParam,
} from '@/api/deduction';

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

// 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;
}

// ── 컴포넌트 ──────────────────────────────────────────────────────────────
export default function DeductionList() {
  const actionRef = useRef<ActionType>();
  const [modal, setModal] = useState<{ open: boolean; editRecord?: DeductionResp }>({
    open: false,
  });

  const { data: statusCodes = [] } = useCommonCodes('DEDUCTION_STATUS');
  const { data: typeCodes = [] } = useCommonCodes('DEDUCTION_TYPE');

  // ── 열기 ───────────────────────────────────────────────────────────────
  const openCreate = () => setModal({ open: true });
  const openEdit = (record: DeductionResp) => setModal({ open: true, editRecord: record });

  // ── 취소 ───────────────────────────────────────────────────────────────
  const onCancel = (record: DeductionResp) => {
    Modal.confirm({
      title: '공제 취소',
      content: `[${record.agentName}] ${record.settleMonth} 공제를 취소하시겠습니까?`,
      okType: 'danger',
      okText: '취소 처리',
      cancelText: '닫기',
      onOk: async () => {
        await deductionApi.cancel(record.deductionId);
        message.success('취소 완료');
        actionRef.current?.reload();
      },
    });
  };

  // ── 저장 ───────────────────────────────────────────────────────────────
  const onSubmit = async (values: Record<string, unknown>) => {
    const req: DeductionSaveReq = {
      agentId: values.agentId as number,
      settleMonth: values.settleMonth as string,
      deductionType: values.deductionType as string,
      amount: values.amount as number,
      description: values.description as string | undefined,
    };

    if (modal.editRecord) {
      await deductionApi.update(modal.editRecord.deductionId, req);
      message.success('수정 완료');
    } else {
      await deductionApi.create(req);
      message.success('등록 완료');
    }
    setModal({ open: false });
    actionRef.current?.reload();
    return true;
  };

  // ── 컬럼 ───────────────────────────────────────────────────────────────
  const columns: ProColumns<DeductionResp>[] = [
    {
      title: '설계사명',
      dataIndex: 'agentName',
      width: 110,
      fixed: 'left',
      search: false,
    },
    {
      title: '설계사ID',
      dataIndex: 'agentId',
      width: 90,
      hideInTable: true,
      valueType: 'digit',
    },
    {
      title: '정산월',
      dataIndex: 'settleMonth',
      width: 90,
      align: 'center',
    },
    {
      title: '차감유형',
      dataIndex: 'deductionType',
      width: 120,
      valueType: 'select',
      valueEnum: Object.fromEntries(
        typeCodes.map((c) => [c.code, { text: c.codeName }]),
      ),
      render: (_, r) => (
        <CodeBadge groupCode="DEDUCTION_TYPE" value={r.deductionType} />
      ),
    },
    {
      title: '금액',
      dataIndex: 'amount',
      width: 130,
      align: 'right',
      search: false,
      render: (_, r) => <MoneyText value={r.amount} />,
    },
    {
      title: '설명',
      dataIndex: 'description',
      width: 200,
      ellipsis: true,
      search: false,
    },
    {
      title: '상태',
      dataIndex: 'status',
      width: 100,
      valueType: 'select',
      valueEnum: Object.fromEntries(
        statusCodes.map((c) => [c.code, { text: c.codeName }]),
      ),
      render: (_, r) => (
        <CodeBadge groupCode="DEDUCTION_STATUS" value={r.status} />
      ),
    },
    {
      title: '등록일',
      dataIndex: 'createdAt',
      width: 160,
      search: false,
      render: (_, r) => dayjs(r.createdAt).format('YYYY-MM-DD HH:mm'),
    },
    {
      title: '액션',
      valueType: 'option',
      width: 140,
      fixed: 'right',
      render: (_, r) =>
        r.status !== 'CANCELLED' ? (
          <Space>
            <PermissionButton
              key="edit"
              menuCode={MENU_CODE}
              permCode="UPDATE"
              size="small"
              type="link"
              onClick={() => openEdit(r)}
            >
              수정
            </PermissionButton>
            <PermissionButton
              key="cancel"
              menuCode={MENU_CODE}
              permCode="UPDATE"
              size="small"
              type="link"
              danger
              onClick={() => onCancel(r)}
            >
              취소
            </PermissionButton>
          </Space>
        ) : null,
    },
  ];

  // ── 렌더링 ─────────────────────────────────────────────────────────────
  return (
    <PageContainer title="공제차감 관리" description="설계사별 정산월 공제 항목 등록 및 관리">
      <ProTable<DeductionResp, DeductionSearchParam>
        actionRef={actionRef}
        rowKey="deductionId"
        columns={columns}
        scroll={{ x: 1100 }}
        request={async (params) => {
          const { current, pageSize, agentId, settleMonth, deductionType, status } =
            params as DeductionSearchParam & { current?: number; pageSize?: number };
          const res = await deductionApi.list({
            agentId,
            settleMonth,
            deductionType,
            status,
            pageNum: current,
            pageSize,
          });
          return { data: res.list, total: res.total, success: true };
        }}
        pagination={{
          pageSize: 30,
          showSizeChanger: true,
          pageSizeOptions: ['20', '50', '100'],
          showTotal: (total) => `총 ${total.toLocaleString()}건`,
        }}
        search={{
          labelWidth: 'auto',
          searchText: '검색',
          resetText: '초기화',
          collapsed: false,
          collapseRender: false,
        }}
        options={{ density: false, fullScreen: true, reload: true, setting: true }}
        toolBarRender={() => [
          <PermissionButton
            key="create"
            menuCode={MENU_CODE}
            permCode="CREATE"
            type="primary"
            onClick={openCreate}
          >
            + 공제 등록
          </PermissionButton>,
        ]}
        dateFormatter="string"
      />

      {/* ── 등록/수정 모달 ─────────────────────────────────────────────── */}
      <ModalForm
        title={modal.editRecord ? '공제 수정' : '공제 등록'}
        open={modal.open}
        onOpenChange={(o) => !o && setModal({ open: false })}
        width={520}
        layout="vertical"
        key={modal.editRecord?.deductionId ?? 'new'}
        initialValues={
          modal.editRecord
            ? {
                agentId: modal.editRecord.agentId,
                settleMonth: modal.editRecord.settleMonth,
                deductionType: modal.editRecord.deductionType,
                amount: modal.editRecord.amount,
                description: modal.editRecord.description,
              }
            : undefined
        }
        onFinish={onSubmit}
        submitter={{
          searchConfig: {
            submitText: modal.editRecord ? '수정' : '등록',
            resetText: '취소',
          },
        }}
        modalProps={{ destroyOnClose: true, maskClosable: false }}
      >
        <ProForm.Group>
          <ProFormDigit
            name="agentId"
            label="설계사 ID"
            rules={[{ required: true, message: '설계사 ID를 입력하세요' }]}
            width="sm"
            min={1}
            fieldProps={{ precision: 0 }}
          />
          <ProFormText
            name="settleMonth"
            label="정산월"
            rules={[
              { required: true, message: '정산월을 입력하세요' },
              {
                validator: (_, v) =>
                  !v || isValidYYYYMM(v)
                    ? Promise.resolve()
                    : Promise.reject(new Error('YYYYMM 6자리로 입력하세요 (예: 202501)')),
              },
            ]}
            width="sm"
            placeholder="예: 202501"
            fieldProps={{ maxLength: 6 }}
          />
        </ProForm.Group>
        <ProForm.Group>
          <ProFormSelect
            name="deductionType"
            label="차감유형"
            rules={[{ required: true, message: '차감유형을 선택하세요' }]}
            width="md"
            options={typeCodes.map((c) => ({ value: c.code, label: c.codeName }))}
          />
          <ProFormDigit
            name="amount"
            label="금액"
            rules={[
              { required: true, message: '금액을 입력하세요' },
              {
                validator: (_: unknown, v: number) =>
                  v === undefined || v === null || v > 0
                    ? Promise.resolve()
                    : Promise.reject(new Error('금액은 양수여야 합니다')),
              },
            ]}
            width="md"
            min={1}
            fieldProps={{
              precision: 0,
              formatter: (v) => `${v}`.replace(/\B(?=(\d{3})+(?!\d))/g, ','),
            }}
          />
        </ProForm.Group>
        <ProFormText
          name="description"
          label="설명"
          width="xl"
          placeholder="공제 사유를 입력하세요"
        />
      </ModalForm>
    </PageContainer>
  );
}
