import { useState, useMemo } from 'react';
import {
  Button, Col, Empty, Input, List, Modal, Row, Space, Switch, Tag, Tooltip, Typography, message,
} from 'antd';
import {
  ProCard, ProTable, ModalForm, ProFormText, ProFormSelect, ProFormTextArea, ProFormSwitch,
  type ProColumns,
} from '@ant-design/pro-components';
import { IconPlus, IconEdit, IconTrash, IconSearch, IconBook } from '@tabler/icons-react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import PageContainer from '@/components/common/PageContainer';
import PermissionButton from '@/components/common/PermissionButton';
import {
  dataDictApi, dataDomainApi,
  DataDictionaryFullResp, DataDictionarySaveReq, DataDomainOption,
} from '@/api/dict';

const { Text } = Typography;

// ─── 테이블명 → 카테고리 자동 분류 ──────────────────────────────────────────

const TABLE_CATEGORY_PREFIX: Array<{ prefix: string; label: string }> = [
  { prefix: 'org_',      label: '조직' },
  { prefix: 'agent_',    label: '조직' },
  { prefix: 'contract_', label: '계약' },
  { prefix: 'policy_',   label: '계약' },
  { prefix: 'ledger_',   label: '원장' },
  { prefix: 'settle_',   label: '정산' },
  { prefix: 'payment_',  label: '정산' },
  { prefix: 'batch_',    label: '정산' },
  { prefix: 'sys_',      label: '시스템' },
  { prefix: 'system_',   label: '시스템' },
  { prefix: 'common_',   label: '시스템' },
  { prefix: 'menu_',     label: '시스템' },
  { prefix: 'user_',     label: '시스템' },
  { prefix: 'role_',     label: '시스템' },
];

function getTableCategory(tableName: string): string {
  for (const { prefix, label } of TABLE_CATEGORY_PREFIX) {
    if (tableName.startsWith(prefix)) return label;
  }
  return '기타';
}

const CATEGORY_ORDER = ['조직', '계약', '원장', '정산', '시스템', '기타'];

// ─── 도메인 카테고리 색상 ─────────────────────────────────────────────────────

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

// ─── 도메인 셀 (Tooltip 포함) ─────────────────────────────────────────────────

function DomainCell({ row }: { row: DataDictionaryFullResp }) {
  if (!row.domainCode) return <span style={{ color: '#bbb' }}>-</span>;
  const tag = (
    <Tag color={DOMAIN_CAT_COLOR[row.domainCategory ?? ''] ?? 'default'} style={{ cursor: 'default' }}>
      {row.domainName ?? row.domainCode}
    </Tag>
  );
  if (!row.formatPattern && !row.dictDescription) return tag;
  return (
    <Tooltip
      title={
        <div>
          <div><Text style={{ color: '#fff', fontSize: 12 }}>코드: {row.domainCode}</Text></div>
          {row.dictDescription && <div><Text style={{ color: '#ddd', fontSize: 12 }}>{row.dictDescription}</Text></div>}
          {row.formatPattern && <div><Text style={{ color: '#adf', fontSize: 12 }}>포맷: {row.formatPattern}</Text></div>}
        </div>
      }
    >
      {tag}
    </Tooltip>
  );
}

// ─── 사전 등록 / 수정 ModalForm ───────────────────────────────────────────────

function DictFormModal({
  row,
  domainOptions,
  onSuccess,
  trigger,
}: {
  row: DataDictionaryFullResp;
  domainOptions: DataDomainOption[];
  onSuccess: () => void;
  trigger: JSX.Element;
}) {
  const isEdit = !!row.domainCode || !!row.columnLabel || !!row.isPk;

  const initialValues: Partial<DataDictionarySaveReq> & { isPkBool?: boolean; isFkBool?: boolean; isRequiredBool?: boolean } = {
    tableName:   row.tableName,
    columnName:  row.columnName,
    columnLabel: row.columnLabel,
    domainCode:  row.domainCode,
    fkReference: row.fkReference,
    defaultValue: row.columnDefault,
    businessRule: row.businessRule,
    sampleValue:  row.sampleValue,
    isPkBool:      row.isPk === 'Y',
    isFkBool:      row.isFk === 'Y',
    isRequiredBool: row.isNullable === 'NO',
  };

  return (
    <ModalForm<DataDictionarySaveReq & { isPkBool?: boolean; isFkBool?: boolean; isRequiredBool?: boolean }>
      title={isEdit ? '사전 수정' : '사전 등록'}
      trigger={trigger}
      width={560}
      modalProps={{ destroyOnClose: true }}
      initialValues={initialValues}
      onFinish={async (values) => {
        const { isPkBool, isFkBool, isRequiredBool, ...rest } = values;
        const payload: DataDictionarySaveReq = {
          ...rest,
          tableName:  row.tableName,
          columnName: row.columnName,
          isPk:       isPkBool ? 'Y' : 'N',
          isFk:       isFkBool ? 'Y' : 'N',
          isRequired: isRequiredBool ? 'Y' : 'N',
        };
        await dataDictApi.create(payload);
        message.success(isEdit ? '수정 완료' : '등록 완료');
        onSuccess();
        return true;
      }}
    >
      <ProFormText name="columnLabel" label="한글 컬럼명" rules={[{ required: true }]} />
      <ProFormSelect
        name="domainCode"
        label="도메인"
        showSearch
        options={domainOptions.map((o) => ({
          value: o.domainCode,
          label: `${o.domainName} (${o.domainCode}) — ${o.domainCategory}`,
        }))}
        fieldProps={{ allowClear: true }}
      />
      <ProFormSwitch name="isPkBool"      label="PK" />
      <ProFormSwitch name="isFkBool"      label="FK" />
      <ProFormSwitch name="isRequiredBool" label="필수 여부" />
      <ProFormText  name="fkReference"  label="FK 참조" placeholder="테이블.컬럼" />
      <ProFormText  name="defaultValue" label="기본값" />
      <ProFormTextArea name="businessRule" label="업무 규칙" fieldProps={{ rows: 2 }} />
      <ProFormText  name="sampleValue" label="샘플 값" />
    </ModalForm>
  );
}

// ─── 우측: 컬럼 사전 테이블 ──────────────────────────────────────────────────

function ColumnDictTable({ tableName }: { tableName: string }) {
  const qc = useQueryClient();

  const { data: domainOptions = [] } = useQuery({
    queryKey: ['dataDomain', 'options'],
    queryFn: dataDomainApi.options,
  });

  const { data: rows = [], isLoading, refetch } = useQuery({
    queryKey: ['dataDict', 'full', tableName],
    queryFn: () => dataDictApi.full(tableName),
    enabled: !!tableName,
  });

  const handleDelete = (dictId: number | undefined) => {
    if (!dictId) return;
    Modal.confirm({
      title: '사전 삭제',
      content: '이 컬럼의 사전 정보를 삭제하시겠습니까?',
      okType: 'danger',
      okText: '삭제',
      cancelText: '취소',
      onOk: async () => {
        await dataDictApi.remove(dictId);
        message.success('삭제 완료');
        qc.invalidateQueries({ queryKey: ['dataDict', 'full', tableName] });
        refetch();
      },
    });
  };

  const columns: ProColumns<DataDictionaryFullResp>[] = [
    {
      title: '#', dataIndex: 'ordinalPosition', width: 50, align: 'right', search: false,
      render: (v) => <Text type="secondary" style={{ fontSize: 12 }}>{v as number}</Text>,
    },
    {
      title: '컬럼명', dataIndex: 'columnName', width: 160, search: false,
      render: (_, r) => (
        <span>
          <Text code style={{ fontSize: 12 }}>{r.columnName}</Text>
          {r.isPk === 'Y' && <Tag color="gold"   style={{ marginLeft: 4, fontSize: 11 }}>PK</Tag>}
          {r.isFk === 'Y' && <Tag color="purple" style={{ marginLeft: 4, fontSize: 11 }}>FK</Tag>}
        </span>
      ),
    },
    {
      title: '한글명', dataIndex: 'columnLabel', width: 140, search: false,
      render: (_, r) =>
        r.columnLabel
          ? <Text>{r.columnLabel}</Text>
          : <Text type="secondary" style={{ fontSize: 12 }}>미등록</Text>,
    },
    {
      title: '도메인', dataIndex: 'domainCode', width: 140, search: false,
      render: (_, r) => <DomainCell row={r} />,
    },
    {
      title: 'DB 타입', dataIndex: 'dataType', width: 100, search: false,
      render: (_, r) => {
        let label = r.dataType;
        if (r.maxLength)    label += `(${r.maxLength})`;
        if (r.numPrecision) label += `(${r.numPrecision}${r.numScale != null ? `,${r.numScale}` : ''})`;
        return <Text style={{ fontSize: 12 }}>{label}</Text>;
      },
    },
    {
      title: 'Nullable', dataIndex: 'isNullable', width: 80, align: 'center', search: false,
      render: (_, r) =>
        r.isNullable === 'NO'
          ? <Tag color="orange">NOT NULL</Tag>
          : <Tag color="default">NULL</Tag>,
    },
    {
      title: '마스킹', dataIndex: 'maskingType', width: 80, search: false,
      render: (_, r) =>
        r.maskingType && r.maskingType !== 'NONE'
          ? <Tag color="orange">{r.maskingType}</Tag>
          : <span style={{ color: '#bbb' }}>-</span>,
    },
    {
      title: '암호화', dataIndex: 'encrypted', width: 75, align: 'center', search: false,
      render: (_, r) =>
        r.encrypted === 'Y'
          ? <Tag color="red">암호화</Tag>
          : <span style={{ color: '#bbb' }}>-</span>,
    },
    {
      title: '샘플', dataIndex: 'sampleValue', width: 100, search: false, ellipsis: true,
      render: (v) => v ?? <span style={{ color: '#bbb' }}>-</span>,
    },
    {
      title: '액션', width: 110, fixed: 'right', search: false,
      render: (_, r) => {
        const hasDictEntry = !!r.columnLabel || !!r.domainCode || !!r.businessRule;
        if (!hasDictEntry) {
          return (
            <DictFormModal
              row={r}
              domainOptions={domainOptions}
              onSuccess={() => { qc.invalidateQueries({ queryKey: ['dataDict', 'full', tableName] }); refetch(); }}
              trigger={
                <PermissionButton
                  menuCode="SYSTEM_DATA_DICT"
                  permCode="CREATE"
                  size="small"
                  type="dashed"
                  icon={<IconPlus size={12} />}
                  style={{ color: '#aaa', borderColor: '#d9d9d9' }}
                >
                  사전 추가
                </PermissionButton>
              }
            />
          );
        }
        return (
          <Space size={2}>
            <DictFormModal
              row={r}
              domainOptions={domainOptions}
              onSuccess={() => { qc.invalidateQueries({ queryKey: ['dataDict', 'full', tableName] }); refetch(); }}
              trigger={
                <PermissionButton
                  menuCode="SYSTEM_DATA_DICT"
                  permCode="UPDATE"
                  size="small"
                  type="text"
                  icon={<IconEdit size={14} />}
                >
                  수정
                </PermissionButton>
              }
            />
            <PermissionButton
              menuCode="SYSTEM_DATA_DICT"
              permCode="DELETE"
              size="small"
              type="text"
              danger
              icon={<IconTrash size={14} />}
              onClick={() => handleDelete(undefined)}
            >
              삭제
            </PermissionButton>
          </Space>
        );
      },
    },
  ];

  return (
    <ProTable<DataDictionaryFullResp>
      rowKey="columnName"
      columns={columns}
      dataSource={rows}
      loading={isLoading}
      search={false}
      pagination={false}
      options={{ density: false, reload: () => refetch(), setting: true }}
      scroll={{ x: 1100 }}
      rowClassName={(r) => {
        const hasDictEntry = !!r.columnLabel || !!r.domainCode || !!r.businessRule;
        return hasDictEntry ? '' : 'dict-row-unregistered';
      }}
      style={{ '--dict-unregistered-bg': '#fafafa' } as React.CSSProperties}
      dateFormatter="string"
    />
  );
}

// ─── 좌측: 테이블 목록 ────────────────────────────────────────────────────────

function TableList({
  selected,
  onSelect,
}: {
  selected: string;
  onSelect: (t: string) => void;
}) {
  const [keyword, setKeyword] = useState('');

  const { data: tables = [], isLoading } = useQuery({
    queryKey: ['dataDict', 'tables'],
    queryFn: dataDictApi.tables,
  });

  const filtered = useMemo(
    () => tables.filter((t) => t.toLowerCase().includes(keyword.toLowerCase())),
    [tables, keyword],
  );

  // 카테고리별 그룹핑
  const grouped = useMemo(() => {
    const map: Record<string, string[]> = {};
    for (const t of filtered) {
      const cat = getTableCategory(t);
      if (!map[cat]) map[cat] = [];
      map[cat].push(t);
    }
    return map;
  }, [filtered]);

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
      <Input
        prefix={<IconSearch size={14} />}
        placeholder="테이블 검색"
        value={keyword}
        onChange={(e) => setKeyword(e.target.value)}
        size="small"
        style={{ marginBottom: 8 }}
        allowClear
      />
      <div style={{ flex: 1, overflow: 'auto' }}>
        {isLoading ? (
          <div style={{ padding: 16, color: '#999', fontSize: 12 }}>로딩 중...</div>
        ) : filtered.length === 0 ? (
          <Empty description="테이블 없음" image={Empty.PRESENTED_IMAGE_SIMPLE} />
        ) : (
          CATEGORY_ORDER.filter((cat) => grouped[cat]?.length).map((cat) => (
            <div key={cat}>
              <div style={{
                padding: '4px 8px',
                fontSize: 11,
                fontWeight: 600,
                color: '#888',
                background: '#f5f5f5',
                letterSpacing: 1,
              }}>
                {cat}
              </div>
              <List
                size="small"
                dataSource={grouped[cat]}
                renderItem={(t) => (
                  <List.Item
                    onClick={() => onSelect(t)}
                    style={{
                      cursor: 'pointer',
                      padding: '4px 12px',
                      background: t === selected ? '#E6F1FB' : undefined,
                      borderLeft: t === selected ? '3px solid #1677ff' : '3px solid transparent',
                      fontSize: 12,
                    }}
                  >
                    <Text
                      code
                      style={{
                        fontSize: 11,
                        color: t === selected ? '#1677ff' : undefined,
                        background: 'transparent',
                        border: 'none',
                      }}
                    >
                      {t}
                    </Text>
                  </List.Item>
                )}
              />
            </div>
          ))
        )}
      </div>
    </div>
  );
}

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

export default function DataDictionary() {
  const [selectedTable, setSelectedTable] = useState('');

  return (
    <PageContainer
      title="데이터 사전"
      description="테이블 컬럼 정의 / 도메인 연결 / 마스킹 및 보안 정책"
    >
      <ProCard split="vertical" style={{ minHeight: 600 }}>
        {/* 좌측: 테이블 목록 */}
        <ProCard
          colSpan={280}
          title={
            <Space>
              <IconBook size={14} style={{ verticalAlign: -2 }} />
              테이블 목록
            </Space>
          }
          headerBordered
          style={{ overflow: 'hidden' }}
          bodyStyle={{ padding: '8px 0', height: 'calc(100vh - 240px)', overflow: 'hidden', display: 'flex', flexDirection: 'column' }}
        >
          <div style={{ padding: '0 8px', flex: 1, overflow: 'hidden', display: 'flex', flexDirection: 'column' }}>
            <TableList selected={selectedTable} onSelect={setSelectedTable} />
          </div>
        </ProCard>

        {/* 우측: 컬럼 사전 */}
        <ProCard
          title={
            selectedTable
              ? <span>컬럼 사전 — <Text code style={{ fontSize: 13 }}>{selectedTable}</Text></span>
              : '컬럼 사전'
          }
          headerBordered
          bodyStyle={{ padding: 0 }}
        >
          {selectedTable ? (
            <ColumnDictTable tableName={selectedTable} />
          ) : (
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: 400 }}>
              <Empty description="좌측에서 테이블을 선택하면 컬럼 사전을 확인할 수 있습니다" />
            </div>
          )}
        </ProCard>
      </ProCard>

      {/* 미등록 행 스타일 */}
      <style>{`
        .dict-row-unregistered td {
          background: #fafafa !important;
          color: #aaa;
        }
      `}</style>
    </PageContainer>
  );
}
