import { useRef, useState } from 'react';
import { Input, Modal, Space, message } from 'antd';
import {
  ModalForm,
  ProForm,
  ProFormDigit,
  ProFormSelect,
  ProFormText,
  ProFormTextArea,
  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 {
  settleCorrectionApi,
  SettleCorrectionResp,
  SettleCorrectionSaveReq,
  SettleCorrectionSearchParam,
} from '@/api/settle-correction';

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

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

// ── 차액 컬러 렌더러 ─────────────────────────────────────────────────────
function DiffAmountCell({ value }: { value: number }) {
  if (value === 0) return <span style={{ color: '#888', fontVariantNumeric: 'tabular-nums' }}>0</span>;
  const color = value > 0 ? '#185FA5' : '#E24B4A';
  const sign = value > 0 ? '+' : '';
  return (
    <span style={{ color, fontVariantNumeric: 'tabular-nums', fontWeight: 600 }}>
      {sign}{value.toLocaleString()}
    </span>
  );
}

// ── 컴포넌트 ──────────────────────────────────────────────────────────────
export default function SettleCorrection() {
  const actionRef = useRef<ActionType>();
  const [createModal, setCreateModal] = useState(false);

  const { data: statusCodes = [] } = useCommonCodes('CORRECTION_STATUS');
  const { data: reasonCodes = [] } = useCommonCodes('CORRECTION_REASON');

  // ── 승인 ───────────────────────────────────────────────────────────────
  const onApprove = (record: SettleCorrectionResp) => {
    Modal.confirm({
      title: '정정 승인',
      content: `[${record.agentName}] ${record.settleMonth} 정산 정정을 승인하시겠습니까?`,
      okText: '승인',
      cancelText: '취소',
      onOk: async () => {
        await settleCorrectionApi.approve(record.correctionId);
        message.success('승인 완료');
        actionRef.current?.reload();
      },
    });
  };

  // ── 취소 ───────────────────────────────────────────────────────────────
  const onCancel = (record: SettleCorrectionResp) => {
    let cancelReason = '';
    Modal.confirm({
      title: '정정 취소',
      content: (
        <Input
          placeholder="취소 사유를 입력하세요"
          onChange={(e) => { cancelReason = e.target.value; }}
        />
      ),
      okType: 'danger',
      okText: '취소 처리',
      cancelText: '닫기',
      onOk: async () => {
        if (!cancelReason.trim()) {
          message.warning('취소 사유를 입력하세요');
          return Promise.reject(new Error('취소 사유 미입력'));
        }
        await settleCorrectionApi.cancel(record.correctionId, cancelReason);
        message.success('취소 완료');
        actionRef.current?.reload();
      },
    });
  };

  // ── 저장 ───────────────────────────────────────────────────────────────
  const onSubmit = async (values: Record<string, unknown>) => {
    const req: SettleCorrectionSaveReq = {
      originalSettleId: values.originalSettleId as number,
      agentId: values.agentId as number,
      settleMonth: values.settleMonth as string,
      beforeAmount: values.beforeAmount as number,
      afterAmount: values.afterAmount as number,
      reasonCode: values.reasonCode as string,
      reasonDetail: values.reasonDetail as string | undefined,
    };
    await settleCorrectionApi.create(req);
    message.success('정정 등록 완료');
    setCreateModal(false);
    actionRef.current?.reload();
    return true;
  };

  // ── 컬럼 ───────────────────────────────────────────────────────────────
  const columns: ProColumns<SettleCorrectionResp>[] = [
    {
      title: '설계사명',
      dataIndex: 'agentName',
      width: 100,
      fixed: 'left',
      search: false,
    },
    {
      title: '설계사ID',
      dataIndex: 'agentId',
      width: 90,
      hideInTable: true,
      valueType: 'digit',
    },
    {
      title: '조직명',
      dataIndex: 'orgName',
      width: 140,
      search: false,
      render: (_, r) => r.orgName ?? '-',
    },
    {
      title: '정산월',
      dataIndex: 'settleMonth',
      width: 90,
      align: 'center',
    },
    {
      title: '정정전금액',
      dataIndex: 'beforeAmount',
      width: 130,
      align: 'right',
      search: false,
      render: (_, r) => <MoneyText value={r.beforeAmount} />,
    },
    {
      title: '정정후금액',
      dataIndex: 'afterAmount',
      width: 130,
      align: 'right',
      search: false,
      render: (_, r) => <MoneyText value={r.afterAmount} />,
    },
    {
      title: '차액',
      dataIndex: 'diffAmount',
      width: 120,
      align: 'right',
      search: false,
      render: (_, r) => <DiffAmountCell value={r.diffAmount} />,
    },
    {
      title: '사유',
      dataIndex: 'reasonCode',
      width: 120,
      valueType: 'select',
      valueEnum: Object.fromEntries(
        reasonCodes.map((c) => [c.code, { text: c.codeName }]),
      ),
      render: (_, r) => (
        <CodeBadge groupCode="CORRECTION_REASON" value={r.reasonCode} />
      ),
    },
    {
      title: '상태',
      dataIndex: 'status',
      width: 100,
      valueType: 'select',
      valueEnum: Object.fromEntries(
        statusCodes.map((c) => [c.code, { text: c.codeName }]),
      ),
      render: (_, r) => (
        <CodeBadge groupCode="CORRECTION_STATUS" value={r.status} />
      ),
    },
    {
      title: '신청자',
      dataIndex: 'requestedByName',
      width: 90,
      search: false,
      render: (_, r) => r.requestedByName ?? '-',
    },
    {
      title: '신청일',
      dataIndex: 'requestedAt',
      width: 150,
      search: false,
      render: (_, r) =>
        r.requestedAt ? dayjs(r.requestedAt).format('YYYY-MM-DD HH:mm') : '-',
    },
    {
      title: '액션',
      valueType: 'option',
      width: 140,
      fixed: 'right',
      render: (_, r) =>
        r.status === 'DRAFT' ? (
          <Space>
            <PermissionButton
              key="approve"
              menuCode={MENU_CODE}
              permCode="APPROVE"
              size="small"
              type="primary"
              onClick={() => onApprove(r)}
            >
              승인
            </PermissionButton>
            <PermissionButton
              key="cancel"
              menuCode={MENU_CODE}
              permCode="UPDATE"
              size="small"
              danger
              onClick={() => onCancel(r)}
            >
              취소
            </PermissionButton>
          </Space>
        ) : null,
    },
  ];

  // ── 렌더링 ─────────────────────────────────────────────────────────────
  return (
    <PageContainer title="정산 정정 관리" description="설계사 정산 금액 정정 요청 및 승인 관리">
      <ProTable<SettleCorrectionResp, SettleCorrectionSearchParam>
        actionRef={actionRef}
        rowKey="correctionId"
        columns={columns}
        scroll={{ x: 1400 }}
        request={async (params) => {
          const { current, pageSize, agentId, settleMonth, status, reasonCode } =
            params as SettleCorrectionSearchParam & {
              current?: number;
              pageSize?: number;
            };
          const res = await settleCorrectionApi.list({
            agentId,
            settleMonth,
            status,
            reasonCode,
            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={() => setCreateModal(true)}
          >
            + 정정 등록
          </PermissionButton>,
        ]}
        dateFormatter="string"
      />

      {/* ── 정정 등록 모달 ─────────────────────────────────────────────── */}
      <ModalForm
        title="정산 정정 등록"
        open={createModal}
        onOpenChange={(o) => !o && setCreateModal(false)}
        width={560}
        layout="vertical"
        key={createModal ? 'correction-open' : 'correction-closed'}
        onFinish={onSubmit}
        submitter={{ searchConfig: { submitText: '등록', resetText: '취소' } }}
        modalProps={{ destroyOnClose: true, maskClosable: false }}
      >
        <ProForm.Group>
          <ProFormDigit
            name="originalSettleId"
            label="원 정산 ID"
            rules={[{ required: true, message: '원 정산 ID를 입력하세요' }]}
            width="sm"
            min={1}
            fieldProps={{ precision: 0 }}
          />
          <ProFormDigit
            name="agentId"
            label="설계사 ID"
            rules={[{ required: true, message: '설계사 ID를 입력하세요' }]}
            width="sm"
            min={1}
            fieldProps={{ precision: 0 }}
          />
        </ProForm.Group>
        <ProForm.Group>
          <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 }}
          />
          <ProFormSelect
            name="reasonCode"
            label="사유코드"
            rules={[{ required: true, message: '사유코드를 선택하세요' }]}
            width="md"
            options={reasonCodes.map((c) => ({ value: c.code, label: c.codeName }))}
          />
        </ProForm.Group>
        <ProForm.Group>
          <ProFormDigit
            name="beforeAmount"
            label="정정전금액"
            rules={[{ required: true, message: '정정전금액을 입력하세요' }]}
            width="md"
            fieldProps={{
              precision: 0,
              formatter: (v) => `${v}`.replace(/\B(?=(\d{3})+(?!\d))/g, ','),
            }}
          />
          <ProFormDigit
            name="afterAmount"
            label="정정후금액"
            rules={[{ required: true, message: '정정후금액을 입력하세요' }]}
            width="md"
            fieldProps={{
              precision: 0,
              formatter: (v) => `${v}`.replace(/\B(?=(\d{3})+(?!\d))/g, ','),
            }}
          />
        </ProForm.Group>
        <ProFormTextArea
          name="reasonDetail"
          label="정정 상세사유"
          width="xl"
          placeholder="정정 사유를 상세히 입력하세요 (선택)"
          fieldProps={{ rows: 4 }}
        />
      </ModalForm>
    </PageContainer>
  );
}
