import { useRef, useState } from 'react';
import {
  Button, Card, Col, Divider, Drawer, Empty, Form, Input, InputNumber,
  message, Modal, Row, Select, Space, Spin, Table, Tag, Tooltip, Typography,
} from 'antd';
import { ProCard, ProTable, ModalForm, ProFormText, ProFormSelect,
  ProFormDigit, ProFormTextArea, type ActionType, type ProColumns,
} from '@ant-design/pro-components';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import {
  IconPlus, IconEdit, IconTrash, IconHistory, IconEye, IconDeviceFloppy,
  IconArrowUp, IconArrowDown, IconWand, IconUpload,
} from '@tabler/icons-react';
import PageContainer from '@/components/common/PageContainer';
import PermissionButton from '@/components/common/PermissionButton';
import CodeBadge from '@/components/common/CodeBadge';
import {
  uploadTemplateApi,
  type UploadTemplateResp,
  type UploadTemplateColumnVO,
  type UploadTemplateSaveReq,
  type TargetFieldMeta,
  type ExcelHeaderResp,
} from '@/api/uploadTemplate';

const { Text } = Typography;

// transformRule → color tag
const RULE_TAG: Record<string, { color: string; label: string }> = {
  TRIM:      { color: 'default',  label: 'TRIM' },
  UPPER:     { color: 'default',  label: 'UPPER' },
  LOWER:     { color: 'default',  label: 'LOWER' },
  DATE:      { color: 'blue',     label: 'DATE' },
  DIVIDE:    { color: 'blue',     label: 'DIVIDE' },
  MULTIPLY:  { color: 'blue',     label: 'MULTIPLY' },
  LOOKUP:    { color: 'green',    label: 'LOOKUP' },
  CODE_MAP:  { color: 'green',    label: 'CODE_MAP' },
  FIXED:     { color: 'orange',   label: 'FIXED' },
  DEFAULT:   { color: 'orange',   label: 'DEFAULT' },
  REPLACE:   { color: 'purple',   label: 'REPLACE' },
  SUBSTRING: { color: 'purple',   label: 'SUBSTRING' },
  CONCAT:    { color: 'purple',   label: 'CONCAT' },
};

const SOURCE_TYPES = [
  { value: 'COLUMN_INDEX', label: '열 인덱스' },
  { value: 'COLUMN_HEADER', label: '열 헤더명' },
  { value: 'FIXED', label: '고정값' },
];

const TARGET_TYPES = [
  { value: 'STRING', label: 'STRING' },
  { value: 'NUMBER', label: 'NUMBER' },
  { value: 'DATE', label: 'DATE' },
  { value: 'BOOLEAN', label: 'BOOLEAN' },
];

const TRANSFORM_RULES = [
  { value: '', label: '없음' },
  { value: 'TRIM', label: 'TRIM' },
  { value: 'UPPER', label: 'UPPER' },
  { value: 'LOWER', label: 'LOWER' },
  { value: 'DATE', label: 'DATE (날짜 변환)' },
  { value: 'DIVIDE', label: 'DIVIDE (나누기)' },
  { value: 'MULTIPLY', label: 'MULTIPLY (곱하기)' },
  { value: 'LOOKUP', label: 'LOOKUP (테이블 조회)' },
  { value: 'CODE_MAP', label: 'CODE_MAP (코드 매핑)' },
  { value: 'FIXED', label: 'FIXED (고정값)' },
  { value: 'DEFAULT', label: 'DEFAULT (기본값)' },
  { value: 'REPLACE', label: 'REPLACE (치환)' },
  { value: 'SUBSTRING', label: 'SUBSTRING (자르기)' },
  { value: 'CONCAT', label: 'CONCAT (연결)' },
];

const CATEGORIES = [
  { value: 'RECRUIT', label: '모집' },
  { value: 'MAINTAIN', label: '유지' },
  { value: 'EXCEPTION', label: '예외' },
  { value: 'PAYMENT', label: '지급' },
  { value: 'ETC', label: '기타' },
];

// ─── 컬럼 매핑 행 타입 (로컬 편집용 key 포함) ───────────────────────────────
interface ColumnRow extends UploadTemplateColumnVO {
  _key: string;
}

function makeKey() {
  return `r_${Date.now()}_${Math.random().toString(36).slice(2)}`;
}

function toRows(cols: UploadTemplateColumnVO[]): ColumnRow[] {
  return cols.map((c) => ({ ...c, _key: makeKey() }));
}

// ─── 변환 규칙에 따라 동적 파라미터 입력 렌더 ──────────────────────────────
function RuleParamCell({ row, onChange }: {
  row: ColumnRow;
  onChange: (key: string, field: keyof UploadTemplateColumnVO, value: unknown) => void;
}) {
  const rule = row.transformRule ?? '';
  if (rule === 'DATE') {
    return (
      <Input
        size="small"
        placeholder="yyyyMMdd"
        value={row.dateFormat ?? ''}
        onChange={(e) => onChange(row._key, 'dateFormat', e.target.value)}
        style={{ width: 100 }}
      />
    );
  }
  if (rule === 'DIVIDE') {
    return (
      <InputNumber
        size="small"
        placeholder="나누는 수"
        value={row.numberDivide}
        onChange={(v) => onChange(row._key, 'numberDivide', v ?? undefined)}
        style={{ width: 100 }}
      />
    );
  }
  if (rule === 'MULTIPLY') {
    return (
      <InputNumber
        size="small"
        placeholder="곱하는 수"
        value={row.numberMultiply}
        onChange={(v) => onChange(row._key, 'numberMultiply', v ?? undefined)}
        style={{ width: 100 }}
      />
    );
  }
  if (rule === 'LOOKUP') {
    return (
      <Input
        size="small"
        placeholder="테이블.컬럼"
        value={row.lookupTable ?? ''}
        onChange={(e) => onChange(row._key, 'lookupTable', e.target.value)}
        style={{ width: 120 }}
      />
    );
  }
  if (rule === 'CODE_MAP') {
    return (
      <Input
        size="small"
        placeholder="그룹코드"
        value={row.codeMapGroup ?? ''}
        onChange={(e) => onChange(row._key, 'codeMapGroup', e.target.value)}
        style={{ width: 100 }}
      />
    );
  }
  if (rule === 'FIXED') {
    return (
      <Input
        size="small"
        placeholder="고정값"
        value={row.fixedValue ?? ''}
        onChange={(e) => onChange(row._key, 'fixedValue', e.target.value)}
        style={{ width: 100 }}
      />
    );
  }
  if (rule === 'DEFAULT') {
    return (
      <Input
        size="small"
        placeholder="기본값"
        value={row.defaultValue ?? ''}
        onChange={(e) => onChange(row._key, 'defaultValue', e.target.value)}
        style={{ width: 100 }}
      />
    );
  }
  if (rule === 'REPLACE' || rule === 'SUBSTRING' || rule === 'CONCAT') {
    return (
      <Input
        size="small"
        placeholder="파라미터"
        value={row.transformParam ?? ''}
        onChange={(e) => onChange(row._key, 'transformParam', e.target.value)}
        style={{ width: 120 }}
      />
    );
  }
  return <Text type="secondary" style={{ fontSize: 12 }}>-</Text>;
}

// ─── 미리보기 파일 선택 모달 ───────────────────────────────────────────────
function PreviewModal({ templateCode, onClose }: { templateCode: string; onClose: () => void }) {
  const [loading, setLoading] = useState(false);
  const [previewRows, setPreviewRows] = useState<Record<string, unknown>[]>([]);
  const [columns, setColumns] = useState<{ title: string; dataIndex: string }[]>([]);
  const inputRef = useRef<HTMLInputElement>(null);

  const handleFile = async (file: File) => {
    setLoading(true);
    try {
      const rows = await uploadTemplateApi.preview(templateCode, file);
      if (rows.length > 0) {
        const keys = Object.keys(rows[0]).filter((k) => k !== 'rowNumber');
        setColumns([
          { title: '행번호', dataIndex: 'rowNumber' },
          ...keys.map((k) => ({ title: k, dataIndex: k })),
        ]);
      }
      setPreviewRows(rows as Record<string, unknown>[]);
    } catch {
      message.error('미리보기 실패');
    } finally {
      setLoading(false);
    }
  };

  return (
    <Modal
      open
      title={`매핑 미리보기 — ${templateCode}`}
      width={900}
      onCancel={onClose}
      footer={<Button onClick={onClose}>닫기</Button>}
    >
      <Space direction="vertical" style={{ width: '100%' }}>
        <Space>
          <Button
            onClick={() => inputRef.current?.click()}
            icon={<IconEye size={14} />}
          >
            파일 선택
          </Button>
          <input
            ref={inputRef}
            type="file"
            accept=".xlsx,.xls,.csv"
            style={{ display: 'none' }}
            onChange={(e) => {
              const f = e.target.files?.[0];
              if (f) handleFile(f);
            }}
          />
          <Text type="secondary" style={{ fontSize: 12 }}>
            Excel / CSV 파일 선택 → 첫 5행 결과 표시
          </Text>
        </Space>
        {loading && <Spin />}
        {previewRows.length > 0 && (
          <Table
            size="small"
            rowKey="rowNumber"
            dataSource={previewRows}
            columns={columns}
            pagination={false}
            scroll={{ x: 800 }}
          />
        )}
      </Space>
    </Modal>
  );
}

// ─── 이력 Drawer ──────────────────────────────────────────────────────────
function HistoryDrawer({ templateId, onClose }: { templateId: number; onClose: () => void }) {
  const { data = [], isLoading } = useQuery({
    queryKey: ['uploadTemplate', 'history', templateId],
    queryFn: () => uploadTemplateApi.history(templateId),
  });

  return (
    <Drawer title="업로드 이력" width={720} open onClose={onClose}>
      <Table
        size="small"
        rowKey="historyId"
        loading={isLoading}
        dataSource={data}
        pagination={{ pageSize: 20 }}
        columns={[
          { title: '파일명', dataIndex: 'fileName', ellipsis: true },
          { title: '전체', dataIndex: 'totalCount', width: 70, align: 'right' },
          { title: '성공', dataIndex: 'successCount', width: 70, align: 'right',
            render: (v) => <Text style={{ color: '#0F6E56' }}>{v}</Text> },
          { title: '오류', dataIndex: 'errorCount', width: 70, align: 'right',
            render: (v) => v > 0 ? <Text type="danger">{v}</Text> : <Text>{v}</Text> },
          { title: '건너뜀', dataIndex: 'skipCount', width: 70, align: 'right' },
          { title: '소요(초)', dataIndex: 'durationSec', width: 80, align: 'right' },
          { title: '업로더', dataIndex: 'uploadedBy', width: 100 },
          { title: '업로드일시', dataIndex: 'uploadedAt', width: 160 },
        ]}
      />
    </Drawer>
  );
}

// ─── 컬럼 매핑 편집기 ─────────────────────────────────────────────────────
function ColumnEditor({ template, onSaved }: {
  template: UploadTemplateResp;
  onSaved: () => void;
}) {
  const [rows, setRows] = useState<ColumnRow[]>([]);
  const [loading, setLoading] = useState(false);
  const [saving, setSaving] = useState(false);
  const [showPreview, setShowPreview] = useState(false);
  const [headerSample, setHeaderSample] = useState<ExcelHeaderResp | null>(null);
  const sampleInputRef = useRef<HTMLInputElement>(null);

  // 선택된 템플릿 변경 시 컬럼 로드
  useQuery({
    queryKey: ['uploadTemplate', 'columns', template.templateId],
    queryFn: () => uploadTemplateApi.getColumns(template.templateId),
    onSuccess: (data: UploadTemplateColumnVO[]) => setRows(toRows(data)),
  } as Parameters<typeof useQuery>[0]);

  // target_table 별 사용 가능한 컬럼 메타 (target_field Select 옵션)
  const { data: targetFields = [] } = useQuery<TargetFieldMeta[]>({
    queryKey: ['uploadTemplate', 'targetFields', template.targetTable],
    queryFn:  () => uploadTemplateApi.targetFields(template.targetTable),
    enabled:  !!template.targetTable,
  });
  const targetFieldOptions = targetFields.map((f) => ({
    value: f.field,
    label: `${f.label} (${f.field})${f.required ? ' *' : ''}`,
    type:  f.type,
  }));
  const targetFieldTypeMap: Record<string, string> = Object.fromEntries(
    targetFields.map((f) => [f.field, f.type]),
  );

  /** 샘플 엑셀 업로드 → 헤더 추출 → 비어있으면 자동 채움 / 있으면 사용자 확인 후 덮어쓰기 */
  const onSampleFile = async (file: File) => {
    try {
      const meta = await uploadTemplateApi.extractHeaders(file, template.headerRow ?? 1, template.sheetIndex ?? 0, 5);
      setHeaderSample(meta);

      const apply = () => {
        // headers 의 길이만큼 행 생성 (sourceColumn=A,B,C, sourceHeader=헤더명)
        const newRows: ColumnRow[] = meta.headers.map((h, idx) => ({
          _key: makeKey(),
          sortOrder: idx + 1,
          sourceType: 'COLUMN_INDEX',
          sourceColumn: meta.columns[idx],
          sourceHeader: h,
          targetField: '',     // 사용자가 Select 로 선택
          targetType: 'STRING',
        }));
        setRows(newRows);
        message.success(`${meta.headers.length}개 컬럼이 자동 추출되었습니다. 대상 필드만 선택해주세요.`);
      };

      if (rows.length > 0) {
        Modal.confirm({
          title: '기존 매핑이 덮어쓰기 됩니다',
          content: `현재 ${rows.length}개 매핑이 있습니다. 샘플 엑셀의 ${meta.headers.length}개 컬럼으로 교체하시겠습니까?`,
          okText: '교체', okType: 'danger',
          onOk: apply,
        });
      } else {
        apply();
      }
    } catch {
      // request.ts interceptor 가 토스트 표시
    }
  };

  const updateCell = (key: string, field: keyof UploadTemplateColumnVO, value: unknown) => {
    setRows((prev) =>
      prev.map((r) => (r._key === key ? { ...r, [field]: value } : r)),
    );
  };

  const addRow = () => {
    setRows((prev) => [
      ...prev,
      {
        _key: makeKey(),
        sortOrder: prev.length + 1,
        sourceType: 'COLUMN_INDEX',
        targetField: '',
        targetType: 'STRING',
      },
    ]);
  };

  const removeRow = (key: string) => {
    setRows((prev) => prev.filter((r) => r._key !== key).map((r, i) => ({ ...r, sortOrder: i + 1 })));
  };

  const moveRow = (key: string, dir: 'up' | 'down') => {
    setRows((prev) => {
      const idx = prev.findIndex((r) => r._key === key);
      if (idx < 0) return prev;
      if (dir === 'up' && idx === 0) return prev;
      if (dir === 'down' && idx === prev.length - 1) return prev;
      const next = [...prev];
      const swap = dir === 'up' ? idx - 1 : idx + 1;
      [next[idx], next[swap]] = [next[swap], next[idx]];
      return next.map((r, i) => ({ ...r, sortOrder: i + 1 }));
    });
  };

  const save = async () => {
    setSaving(true);
    try {
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      const payload: UploadTemplateColumnVO[] = rows.map(({ _key, ...rest }) => rest);
      await uploadTemplateApi.saveColumns(template.templateId, payload);
      message.success('컬럼 매핑이 저장되었습니다');
      onSaved();
    } catch {
      // request.ts interceptor handles toast
    } finally {
      setSaving(false);
    }
  };

  if (loading) return <Spin style={{ margin: 32 }} />;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
      {/* 헤더 */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
        <Space wrap>
          <Text strong>{template.templateName}</Text>
          <Tag>{template.templateCode}</Tag>
          <Tag color="blue">{template.category}</Tag>
          <Tag color="purple">→ {template.targetTable}</Tag>
          <CodeBadge groupCode="ACTIVE_YN" value={template.isActive} />
        </Space>
        <Space>
          {/* 샘플 엑셀 자동 채우기 */}
          <input
            ref={sampleInputRef}
            type="file"
            accept=".xlsx,.xls"
            style={{ display: 'none' }}
            onChange={(e) => {
              const f = e.target.files?.[0];
              if (f) onSampleFile(f);
              e.target.value = '';
            }}
          />
          <Tooltip title="샘플 엑셀 파일을 업로드하면 첫 행의 헤더를 자동으로 추출해서 컬럼을 채웁니다">
            <Button
              size="small"
              icon={<IconWand size={14} />}
              onClick={() => sampleInputRef.current?.click()}
            >
              샘플 엑셀로 자동 채우기
            </Button>
          </Tooltip>
          <Button size="small" icon={<IconEye size={14} />} onClick={() => setShowPreview(true)}>
            미리보기
          </Button>
          <PermissionButton
            menuCode="SYSTEM_UPLOAD_TEMPLATE"
            permCode="UPDATE"
            type="primary"
            size="small"
            icon={<IconDeviceFloppy size={14} />}
            loading={saving}
            onClick={save}
          >
            저장
          </PermissionButton>
        </Space>
      </div>

      {/* 샘플 미리보기 (자동 채우기 후 첫 5행) */}
      {headerSample && headerSample.samples.length > 0 && (
        <div style={{
          background: '#fafafa', border: '1px solid #f0f0f0', borderRadius: 8,
          padding: '10px 12px', marginBottom: 12,
        }}>
          <div style={{ fontSize: 12, color: '#666', marginBottom: 6 }}>
            <IconUpload size={12} style={{ verticalAlign: -2, marginRight: 4 }} />
            샘플 데이터 (첫 5행)
          </div>
          <div style={{ overflow: 'auto' }}>
            <Table
              size="small"
              pagination={false}
              dataSource={headerSample.samples.map((row, idx) => ({
                _idx: idx,
                ...Object.fromEntries(headerSample.headers.map((h, i) => [h, row[i]])),
              }))}
              rowKey="_idx"
              columns={headerSample.headers.map((h, idx) => ({
                title: <span><Tag color="blue" style={{ marginRight: 4 }}>{headerSample.columns[idx]}</Tag>{h}</span>,
                dataIndex: h,
                width: 120,
              }))}
              scroll={{ x: 'max-content' }}
            />
          </div>
        </div>
      )}

      {/* 컬럼 테이블 */}
      <div style={{ flex: 1, overflow: 'auto' }}>
        <Table<ColumnRow>
          size="small"
          rowKey="_key"
          dataSource={rows}
          pagination={false}
          scroll={{ x: 1100 }}
          footer={() => (
            <PermissionButton
              menuCode="SYSTEM_UPLOAD_TEMPLATE"
              permCode="UPDATE"
              size="small"
              icon={<IconPlus size={14} />}
              onClick={addRow}
            >
              행 추가
            </PermissionButton>
          )}
          columns={[
            {
              title: '순서', dataIndex: 'sortOrder', width: 60, align: 'center',
              render: (_, r) => (
                <Space size={2}>
                  <Tooltip title="위로">
                    <Button size="small" type="text" icon={<IconArrowUp size={12} />}
                      onClick={() => moveRow(r._key, 'up')} />
                  </Tooltip>
                  <Tooltip title="아래로">
                    <Button size="small" type="text" icon={<IconArrowDown size={12} />}
                      onClick={() => moveRow(r._key, 'down')} />
                  </Tooltip>
                </Space>
              ),
            },
            {
              title: '소스 유형', dataIndex: 'sourceType', width: 120,
              render: (_, r) => (
                <Select
                  size="small"
                  value={r.sourceType}
                  options={SOURCE_TYPES}
                  onChange={(v) => updateCell(r._key, 'sourceType', v)}
                  style={{ width: '100%' }}
                />
              ),
            },
            {
              title: '소스 컬럼', dataIndex: 'sourceColumn', width: 80,
              render: (_, r) => (
                <Input
                  size="small"
                  value={r.sourceType === 'COLUMN_HEADER' ? (r.sourceHeader ?? '') : (r.sourceColumn ?? '')}
                  placeholder={r.sourceType === 'COLUMN_HEADER' ? '헤더명' : '열 번호'}
                  onChange={(e) => {
                    if (r.sourceType === 'COLUMN_HEADER') {
                      updateCell(r._key, 'sourceHeader', e.target.value);
                    } else {
                      updateCell(r._key, 'sourceColumn', e.target.value);
                    }
                  }}
                />
              ),
            },
            {
              title: '대상 필드', dataIndex: 'targetField', width: 200,
              render: (_, r) => (
                <Select
                  size="small"
                  value={r.targetField || undefined}
                  showSearch
                  allowClear
                  placeholder="DB 컬럼 선택"
                  optionFilterProp="label"
                  options={targetFieldOptions}
                  onChange={(v) => {
                    updateCell(r._key, 'targetField', v ?? '');
                    // 타입 자동 채우기
                    if (v && targetFieldTypeMap[v]) {
                      updateCell(r._key, 'targetType', targetFieldTypeMap[v]);
                    }
                  }}
                  style={{ width: '100%' }}
                  notFoundContent={targetFields.length === 0 ? '메타 로딩 중...' : '일치하는 필드 없음'}
                />
              ),
            },
            {
              title: '대상 타입', dataIndex: 'targetType', width: 100,
              render: (_, r) => (
                <Select
                  size="small"
                  value={r.targetType}
                  options={TARGET_TYPES}
                  onChange={(v) => updateCell(r._key, 'targetType', v)}
                  style={{ width: '100%' }}
                />
              ),
            },
            {
              title: '변환 규칙', dataIndex: 'transformRule', width: 140,
              render: (_, r) => (
                <Select
                  size="small"
                  value={r.transformRule ?? ''}
                  options={TRANSFORM_RULES}
                  onChange={(v) => updateCell(r._key, 'transformRule', v || undefined)}
                  style={{ width: '100%' }}
                  dropdownMatchSelectWidth={false}
                />
              ),
            },
            {
              title: '파라미터', width: 130,
              render: (_, r) => <RuleParamCell row={r} onChange={updateCell} />,
            },
            {
              title: '필수', dataIndex: 'isRequired', width: 60, align: 'center',
              render: (_, r) => (
                <Select
                  size="small"
                  value={r.isRequired ?? 'N'}
                  options={[{ value: 'Y', label: <Tag color="error" style={{ margin: 0 }}>Y</Tag> }, { value: 'N', label: 'N' }]}
                  onChange={(v) => updateCell(r._key, 'isRequired', v)}
                  style={{ width: 60 }}
                />
              ),
            },
            {
              title: '액션', width: 60, align: 'center', fixed: 'right',
              render: (_, r) => (
                <PermissionButton
                  menuCode="SYSTEM_UPLOAD_TEMPLATE"
                  permCode="DELETE"
                  size="small"
                  type="text"
                  danger
                  icon={<IconTrash size={14} />}
                  onClick={() => removeRow(r._key)}
                />
              ),
            },
          ]}
        />
      </div>

      {showPreview && (
        <PreviewModal
          templateCode={template.templateCode}
          onClose={() => setShowPreview(false)}
        />
      )}
    </div>
  );
}

// ─── 템플릿 등록 / 수정 모달 폼 ─────────────────────────────────────────
function TemplateFormModal({ editTarget, onSuccess, trigger }: {
  editTarget?: UploadTemplateResp;
  onSuccess: () => void;
  trigger: JSX.Element;
}) {
  return (
    <ModalForm<UploadTemplateSaveReq>
      title={editTarget ? '템플릿 수정' : '템플릿 등록'}
      trigger={trigger}
      width={560}
      modalProps={{ destroyOnClose: true }}
      initialValues={editTarget ?? { headerRow: 1, dataStartRow: 2, sheetIndex: 0, batchSize: 1000, isActive: 'Y' }}
      onFinish={async (values) => {
        if (editTarget) {
          await uploadTemplateApi.update(editTarget.templateId, values);
          message.success('수정 완료');
        } else {
          await uploadTemplateApi.create(values);
          message.success('등록 완료');
        }
        onSuccess();
        return true;
      }}
    >
      <Row gutter={16}>
        <Col span={12}>
          <ProFormText name="templateCode" label="템플릿 코드" rules={[{ required: true }]}
            fieldProps={{ disabled: !!editTarget }} />
        </Col>
        <Col span={12}>
          <ProFormText name="templateName" label="템플릿 명" rules={[{ required: true }]} />
        </Col>
        <Col span={12}>
          <ProFormSelect name="category" label="카테고리" rules={[{ required: true }]}
            options={CATEGORIES} />
        </Col>
        <Col span={12}>
          <ProFormSelect
            name="targetTable" label="대상 테이블"
            rules={[{ required: true, message: '필수입니다' }]}
            request={async () => {
              const tables = await uploadTemplateApi.targetTables();
              return tables.map((t) => ({ value: t, label: t }));
            }}
            placeholder="recruit_ledger 등 선택"
          />
        </Col>
        <Col span={12}>
          <ProFormText name="companyCode" label="보험사 코드" />
        </Col>
        <Col span={12}>
          <ProFormSelect name="isActive" label="활성여부"
            options={[{ value: 'Y', label: '활성' }, { value: 'N', label: '비활성' }]} />
        </Col>
        <Col span={8}>
          <ProFormDigit name="headerRow" label="헤더 행" min={0} />
        </Col>
        <Col span={8}>
          <ProFormDigit name="dataStartRow" label="데이터 시작 행" min={1} />
        </Col>
        <Col span={8}>
          <ProFormDigit name="sheetIndex" label="시트 인덱스" min={0} />
        </Col>
        <Col span={12}>
          <ProFormText name="sheetName" label="시트 이름" />
        </Col>
        <Col span={12}>
          <ProFormDigit name="batchSize" label="배치 크기" min={1} />
        </Col>
        <Col span={24}>
          <ProFormTextArea name="description" label="설명" fieldProps={{ rows: 2 }} />
        </Col>
      </Row>
    </ModalForm>
  );
}

// ─── 메인 페이지 ──────────────────────────────────────────────────────────
export default function UploadTemplateManager() {
  const qc = useQueryClient();
  const actionRef = useRef<ActionType>();
  const [selected, setSelected] = useState<UploadTemplateResp | null>(null);
  const [historyTarget, setHistoryTarget] = useState<UploadTemplateResp | null>(null);
  const [editTarget, setEditTarget] = useState<UploadTemplateResp | undefined>();

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

  const handleDelete = (id: number) =>
    Modal.confirm({
      title: '삭제 확인',
      content: '이 템플릿을 삭제하시겠습니까?',
      okType: 'danger',
      onOk: async () => {
        await uploadTemplateApi.remove(id);
        message.success('삭제 완료');
        if (selected?.templateId === id) setSelected(null);
        refresh();
      },
    });

  const columns: ProColumns<UploadTemplateResp>[] = [
    {
      title: '검색어', dataIndex: 'searchKeyword', hideInTable: true,
      fieldProps: { placeholder: '코드 / 이름' },
    },
    {
      title: '카테고리', dataIndex: 'category', width: 90, valueType: 'select',
      valueEnum: Object.fromEntries(CATEGORIES.map((c) => [c.value, { text: c.label }])),
      render: (_, r) => <Tag>{r.category}</Tag>,
    },
    { title: '코드', dataIndex: 'templateCode', width: 160, search: false, ellipsis: true },
    { title: '이름', dataIndex: 'templateName', search: false, ellipsis: true },
    {
      title: '활성', dataIndex: 'isActive', width: 70, align: 'center', search: false,
      render: (_, r) => <Tag color={r.isActive === 'Y' ? 'success' : 'default'}>{r.isActive}</Tag>,
    },
    {
      title: '액션', width: 140, fixed: 'right', search: false,
      render: (_, r) => (
        <Space size={2}>
          <TemplateFormModal
            editTarget={r}
            onSuccess={refresh}
            trigger={
              <PermissionButton menuCode="SYSTEM_UPLOAD_TEMPLATE" permCode="UPDATE"
                size="small" type="text" icon={<IconEdit size={14} />}
                onClick={() => setEditTarget(r)}
              >
                수정
              </PermissionButton>
            }
          />
          <PermissionButton menuCode="SYSTEM_UPLOAD_TEMPLATE" permCode="DELETE"
            size="small" type="text" danger icon={<IconTrash size={14} />}
            onClick={() => handleDelete(r.templateId)}
          >
            삭제
          </PermissionButton>
          <Tooltip title="이력">
            <Button size="small" type="text" icon={<IconHistory size={14} />}
              onClick={() => setHistoryTarget(r)} />
          </Tooltip>
        </Space>
      ),
    },
  ];

  return (
    <PageContainer
      title="업로드 템플릿 관리"
      description="엑셀 / CSV 업로드 매핑 템플릿 등록 및 컬럼 매핑 편집"
      extra={
        <TemplateFormModal
          onSuccess={refresh}
          trigger={
            <PermissionButton menuCode="SYSTEM_UPLOAD_TEMPLATE" permCode="CREATE"
              type="primary" icon={<IconPlus size={14} />}
            >
              템플릿 등록
            </PermissionButton>
          }
        />
      }
    >
      <ProCard split="vertical" style={{ minHeight: 600 }}>
        {/* 좌측: 템플릿 목록 */}
        <ProCard colSpan={380} style={{ overflow: 'hidden' }}>
          <ProTable<UploadTemplateResp>
            actionRef={actionRef}
            rowKey="templateId"
            columns={columns}
            onRow={(r) => ({
              onClick: () => setSelected(r),
              style: {
                cursor: 'pointer',
                background: r.templateId === selected?.templateId ? '#E6F1FB' : undefined,
              },
            })}
            request={async (params) => {
              const { current, pageSize, ...rest } = params as {
                current: number;
                pageSize: number;
                category?: string;
                searchKeyword?: string;
              };
              const res = await uploadTemplateApi.list({ ...rest, pageNum: current, pageSize });
              return { data: res.list, total: res.total, success: true };
            }}
            pagination={{ pageSize: 20, showTotal: (t) => `총 ${t}건` }}
            search={{ labelWidth: 'auto', searchText: '검색', resetText: '초기화', collapsed: false, collapseRender: false }}
            options={{ density: false, reload: true }}
            dateFormatter="string"
            scroll={{ x: 380 }}
          />
        </ProCard>

        {/* 우측: 컬럼 매핑 편집기 */}
        <ProCard style={{ padding: 16 }}>
          {selected ? (
            <ColumnEditor
              key={selected.templateId}
              template={selected}
              onSaved={() => qc.invalidateQueries({ queryKey: ['uploadTemplate', 'columns', selected.templateId] })}
            />
          ) : (
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: 400 }}>
              <Empty description="좌측에서 템플릿을 선택하면 컬럼 매핑을 편집할 수 있습니다" />
            </div>
          )}
        </ProCard>
      </ProCard>

      {/* 이력 Drawer */}
      {historyTarget && (
        <HistoryDrawer
          templateId={historyTarget.templateId}
          onClose={() => setHistoryTarget(null)}
        />
      )}
    </PageContainer>
  );
}
