import { useRef } from 'react';
import { Modal, Space, Switch, Tag, Tooltip, message } from 'antd';
import {
  ProTable, ModalForm, ProFormText, ProFormSelect, ProFormDigit,
  ProFormTextArea, ProFormSwitch,
  type ActionType, type ProColumns,
} from '@ant-design/pro-components';
import { IconPlus, IconEdit, IconTrash } from '@tabler/icons-react';
import { useQueryClient } from '@tanstack/react-query';
import PageContainer from '@/components/common/PageContainer';
import PermissionButton from '@/components/common/PermissionButton';
import { dataDomainApi, DataDomainResp, DataDomainSaveReq } from '@/api/dict';

// ─── 카테고리 색상 ────────────────────────────────────────────────────────────

const CATEGORY_COLOR: Record<string, string> = {
  IDENTIFIER: 'blue',
  PII:        'red',
  MONEY:      'green',
  RATE:       'cyan',
  DATE:       'purple',
  CODE:       'orange',
  TEXT:       'default',
  JSON:       'magenta',
};

const CATEGORY_OPTIONS = Object.keys(CATEGORY_COLOR).map((v) => ({ value: v, label: v }));

const DATA_TYPE_OPTIONS = [
  'VARCHAR', 'CHAR', 'TEXT', 'INT', 'BIGINT', 'SMALLINT',
  'DECIMAL', 'NUMERIC', 'FLOAT', 'DOUBLE', 'DATE', 'DATETIME',
  'TIMESTAMP', 'BOOLEAN', 'JSON',
].map((v) => ({ value: v, label: v }));

const MASKING_OPTIONS = [
  { value: 'NONE',    label: 'NONE' },
  { value: 'NAME',    label: 'NAME' },
  { value: 'PHONE',   label: 'PHONE' },
  { value: 'RRN',     label: 'RRN' },
  { value: 'ACCOUNT', label: 'ACCOUNT' },
  { value: 'EMAIL',   label: 'EMAIL' },
];

const MASKING_COLOR: Record<string, string> = {
  NONE:    'default',
  NAME:    'orange',
  PHONE:   'orange',
  RRN:     'red',
  ACCOUNT: 'red',
  EMAIL:   'orange',
};

// ─── 도메인 등록 / 수정 ModalForm ─────────────────────────────────────────────

function DomainFormModal({
  editTarget,
  onSuccess,
  trigger,
}: {
  editTarget?: DataDomainResp;
  onSuccess: () => void;
  trigger: JSX.Element;
}) {
  const isEdit = !!editTarget;

  return (
    <ModalForm<DataDomainSaveReq & { encryptedBool?: boolean }>
      title={isEdit ? '도메인 수정' : '도메인 등록'}
      trigger={trigger}
      width={640}
      modalProps={{ destroyOnClose: true }}
      initialValues={
        editTarget
          ? { ...editTarget, encryptedBool: editTarget.encrypted === 'Y' }
          : { isActive: 'Y', encrypted: 'N', encryptedBool: false }
      }
      onFinish={async (values) => {
        const { encryptedBool, ...rest } = values;
        const payload: DataDomainSaveReq = {
          ...rest,
          encrypted: encryptedBool ? 'Y' : 'N',
          isActive: rest.isActive ?? 'Y',
        };
        if (isEdit) {
          await dataDomainApi.update(editTarget!.domainCode, payload);
          message.success('수정 완료');
        } else {
          await dataDomainApi.create(payload);
          message.success('등록 완료');
        }
        onSuccess();
        return true;
      }}
    >
      <ProFormText
        name="domainCode"
        label="도메인 코드"
        rules={[{ required: true }]}
        fieldProps={{ disabled: isEdit }}
        placeholder="예: AGENT_CODE"
      />
      <ProFormText
        name="domainName"
        label="도메인 명"
        rules={[{ required: true }]}
      />
      <ProFormSelect
        name="domainCategory"
        label="카테고리"
        rules={[{ required: true }]}
        options={CATEGORY_OPTIONS}
      />
      <ProFormSelect
        name="dataType"
        label="데이터 타입"
        rules={[{ required: true }]}
        options={DATA_TYPE_OPTIONS}
      />
      <ProFormDigit name="length"    label="길이"       min={0} />
      <ProFormDigit name="precision" label="전체 자릿수" min={0} />
      <ProFormDigit name="scale"     label="소수 자릿수" min={0} />
      <ProFormText  name="formatPattern"    label="포맷 패턴"    placeholder="예: YYYY-MM-DD" />
      <ProFormText  name="validationRegex"  label="검증 정규식"  />
      <ProFormText  name="exampleValue"     label="예시 값"      />
      <ProFormSelect
        name="maskingType"
        label="마스킹 유형"
        options={MASKING_OPTIONS}
      />
      <ProFormSwitch name="encryptedBool" label="암호화 여부" />
      <ProFormTextArea name="description" label="설명" fieldProps={{ rows: 2 }} />
      <ProFormSelect
        name="isActive"
        label="활성 여부"
        options={[{ value: 'Y', label: '활성' }, { value: 'N', label: '비활성' }]}
      />
    </ModalForm>
  );
}

// ─── 메인 ─────────────────────────────────────────────────────────────────────

export default function DataDomainList() {
  const qc = useQueryClient();
  const actionRef = useRef<ActionType>();

  const refresh = () => {
    qc.invalidateQueries({ queryKey: ['dataDomain'] });
    actionRef.current?.reload();
  };

  const handleDelete = (domainCode: string) =>
    Modal.confirm({
      title: '도메인 삭제',
      content: '이 도메인을 삭제하시겠습니까? 사용 중인 컬럼이 있으면 오류가 반환됩니다.',
      okType: 'danger',
      okText: '삭제',
      cancelText: '취소',
      onOk: async () => {
        await dataDomainApi.remove(domainCode);
        message.success('삭제 완료');
        refresh();
      },
    });

  const columns: ProColumns<DataDomainResp>[] = [
    // 검색 전용
    {
      title: '카테고리', dataIndex: 'domainCategory', valueType: 'select',
      valueEnum: Object.fromEntries(CATEGORY_OPTIONS.map((o) => [o.value, { text: o.label }])),
      hideInTable: true,
    },
    {
      title: '활성 여부', dataIndex: 'isActive', valueType: 'select',
      valueEnum: { Y: { text: '활성' }, N: { text: '비활성' } },
      hideInTable: true,
    },
    {
      title: '검색어', dataIndex: 'searchKeyword', hideInTable: true,
      fieldProps: { placeholder: '코드 / 이름' },
    },

    // 테이블 컬럼
    { title: '도메인 코드', dataIndex: 'domainCode', width: 160, search: false, copyable: true },
    { title: '도메인 명',   dataIndex: 'domainName', width: 160, search: false },
    {
      title: '카테고리', dataIndex: 'domainCategory', width: 110, search: false,
      render: (_, r) => (
        <Tag color={CATEGORY_COLOR[r.domainCategory] ?? 'default'}>{r.domainCategory}</Tag>
      ),
    },
    { title: '데이터 타입', dataIndex: 'dataType', width: 110, search: false },
    {
      title: '길이 / 정밀도', width: 110, search: false,
      render: (_, r) => {
        if (r.precision != null) {
          return <span>{r.precision}{r.scale != null ? `,${r.scale}` : ''}</span>;
        }
        return r.length != null ? <span>{r.length}</span> : <span style={{ color: '#bbb' }}>-</span>;
      },
    },
    {
      title: '포맷 패턴', dataIndex: 'formatPattern', width: 130, search: false,
      render: (v) => v ?? <span style={{ color: '#bbb' }}>-</span>,
    },
    {
      title: '마스킹', dataIndex: 'maskingType', width: 90, search: false,
      render: (_, r) =>
        r.maskingType && r.maskingType !== 'NONE' ? (
          <Tag color={MASKING_COLOR[r.maskingType] ?? 'default'}>{r.maskingType}</Tag>
        ) : (
          <span style={{ color: '#bbb' }}>-</span>
        ),
    },
    {
      title: '암호화', dataIndex: 'encrypted', width: 80, align: 'center', search: false,
      render: (_, r) =>
        r.encrypted === 'Y' ? <Tag color="red">암호화</Tag> : <span style={{ color: '#bbb' }}>-</span>,
    },
    {
      title: '활성', dataIndex: 'isActive', width: 70, align: 'center', search: false,
      render: (_, r) => (
        <Switch checked={r.isActive === 'Y'} size="small" disabled />
      ),
    },
    {
      title: '액션', width: 130, fixed: 'right', search: false,
      render: (_, r) => (
        <Space size={2}>
          <DomainFormModal
            editTarget={r}
            onSuccess={refresh}
            trigger={
              <PermissionButton
                menuCode="SYSTEM_DATA_DOMAIN"
                permCode="UPDATE"
                size="small"
                type="text"
                icon={<IconEdit size={14} />}
              >
                수정
              </PermissionButton>
            }
          />
          <PermissionButton
            menuCode="SYSTEM_DATA_DOMAIN"
            permCode="DELETE"
            size="small"
            type="text"
            danger
            icon={<IconTrash size={14} />}
            onClick={() => handleDelete(r.domainCode)}
          >
            삭제
          </PermissionButton>
        </Space>
      ),
    },
  ];

  return (
    <PageContainer
      title="데이터 도메인 사전"
      description="컬럼 도메인 정의 및 마스킹 / 암호화 정책 관리"
      extra={
        <DomainFormModal
          onSuccess={refresh}
          trigger={
            <PermissionButton
              menuCode="SYSTEM_DATA_DOMAIN"
              permCode="CREATE"
              type="primary"
              icon={<IconPlus size={14} />}
            >
              도메인 등록
            </PermissionButton>
          }
        />
      }
    >
      <ProTable<DataDomainResp>
        actionRef={actionRef}
        rowKey="domainCode"
        columns={columns}
        scroll={{ x: 1200 }}
        request={async (params) => {
          const { current, pageSize, domainCategory, isActive, searchKeyword } = params as {
            current: number;
            pageSize: number;
            domainCategory?: string;
            isActive?: string;
            searchKeyword?: string;
          };
          const res = await dataDomainApi.list({ domainCategory, isActive, searchKeyword, 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 }}
        dateFormatter="string"
      />
    </PageContainer>
  );
}
