import { useState, useEffect, useCallback } from 'react';

// ─── 타입 ──────────────────────────────────────────────────

type TaskStatus = '완료' | '진행중' | '대기' | '오류';

interface AuditLogEntry {
  id: string;
  time: string;
  operator: string;
  operatorId: string;
  action: string;
  targetData: string;
  result: string;
  resultType: '성공' | '실패' | '거부' | '진행중';
  ip: string;
  browser: string;
  detail: {
    dataCount: number;
    rulesApplied: string;
    processedCount: number;
    errorCount: number;
  };
}

interface DeidentifyTask {
  id: string;
  name: string;
  target: string;
  status: TaskStatus;
  startTime: string;
  progress: number;
  createdBy: string;
}

type SourceType = 'db' | 'file' | 'api';
type ProcessMode = 'immediate' | 'scheduled' | 'oneshot';
type RepeatType = 'daily' | 'weekly' | 'monthly';
type DeidentifyTechnique = '마스킹' | '삭제' | '범주화' | '암호화' | '샘플링' | '가명처리' | '유지';

interface FieldConfig {
  name: string;
  dataType: string;
  technique: DeidentifyTechnique;
  configValue: string;
  selected: boolean;
}

interface DbConfig {
  host: string;
  port: string;
  database: string;
  tableName: string;
}

interface ApiConfig {
  url: string;
  method: 'GET' | 'POST';
}

interface ScheduleConfig {
  hour: string;
  repeatType: RepeatType;
  weekday: string;
  startDate: string;
  notifyOnComplete: boolean;
  notifyOnError: boolean;
}

interface OneshotConfig {
  date: string;
  hour: string;
}

interface WizardState {
  step: number;
  taskName: string;
  sourceType: SourceType;
  dbConfig: DbConfig;
  apiConfig: ApiConfig;
  fields: FieldConfig[];
  processMode: ProcessMode;
  scheduleConfig: ScheduleConfig;
  oneshotConfig: OneshotConfig;
  saveAsTemplate: boolean;
  applyTemplate: string;
  confirmed: boolean;
}

// ─── Mock 데이터 ────────────────────────────────────────────

const MOCK_TASKS: DeidentifyTask[] = [
  {
    id: '001',
    name: 'customer_2024',
    target: '선박/운항 - 선장·선원 성명',
    status: '완료',
    startTime: '2026-04-10 14:30',
    progress: 100,
    createdBy: '관리자',
  },
  {
    id: '002',
    name: 'transaction_04',
    target: '사고 현장 - 현장사진, 영상내 인물',
    status: '진행중',
    startTime: '2026-04-10 14:15',
    progress: 82,
    createdBy: '김담당',
  },
  {
    id: '003',
    name: 'employee_info',
    target: '인사정보 - 계정, 로그인 정보',
    status: '대기',
    startTime: '2026-04-10 22:00',
    progress: 0,
    createdBy: '이담당',
  },
  {
    id: '004',
    name: 'vendor_data',
    target: 'HNS 대응 - 화학물질 취급자, 방제업체 연락처',
    status: '오류',
    startTime: '2026-04-09 13:45',
    progress: 45,
    createdBy: '관리자',
  },
  {
    id: '005',
    name: 'partner_contacts',
    target: '시스템 운영 - 관리자, 운영자 접속로그',
    status: '완료',
    startTime: '2026-04-08 09:00',
    progress: 100,
    createdBy: '박담당',
  },
];

const DEFAULT_FIELDS: FieldConfig[] = [
  { name: '고객ID', dataType: '문자열', technique: '삭제', configValue: '-', selected: true },
  {
    name: '이름',
    dataType: '문자열',
    technique: '마스킹',
    configValue: '*로 치환',
    selected: true,
  },
  {
    name: '휴대폰',
    dataType: '문자열',
    technique: '마스킹',
    configValue: '010-****-****',
    selected: true,
  },
  {
    name: '주소',
    dataType: '문자열',
    technique: '범주화',
    configValue: '시/도만 표시',
    selected: true,
  },
  {
    name: '이메일',
    dataType: '문자열',
    technique: '가명처리',
    configValue: '키: random_001',
    selected: true,
  },
  {
    name: '생년월일',
    dataType: '날짜',
    technique: '범주화',
    configValue: '연도만 표시',
    selected: true,
  },
  { name: '회사', dataType: '문자열', technique: '유지', configValue: '변경 없음', selected: true },
];

const TECHNIQUES: DeidentifyTechnique[] = [
  '마스킹',
  '삭제',
  '범주화',
  '암호화',
  '샘플링',
  '가명처리',
  '유지',
];

const HOURS = Array.from({ length: 24 }, (_, i) => `${String(i).padStart(2, '0')}:00`);

const WEEKDAYS = ['월', '화', '수', '목', '금', '토', '일'];

const TEMPLATES = ['기본 개인정보', '금융데이터', '의료데이터'];

const MOCK_AUDIT_LOGS: Record<string, AuditLogEntry[]> = {
  '001': [
    {
      id: 'LOG_20260410_001',
      time: '2026-04-10 14:30:45',
      operator: '김철수',
      operatorId: 'user_12345',
      action: '처리완료',
      targetData: 'customer_2024',
      result: '성공 (100%)',
      resultType: '성공',
      ip: '192.168.1.100',
      browser: 'Chrome 123.0',
      detail: {
        dataCount: 15240,
        rulesApplied: '마스킹 3, 범주화 2, 삭제 2',
        processedCount: 15240,
        errorCount: 0,
      },
    },
    {
      id: 'LOG_20260410_002',
      time: '2026-04-10 14:15:10',
      operator: '김철수',
      operatorId: 'user_12345',
      action: '처리시작',
      targetData: 'customer_2024',
      result: '성공',
      resultType: '성공',
      ip: '192.168.1.100',
      browser: 'Chrome 123.0',
      detail: {
        dataCount: 15240,
        rulesApplied: '마스킹 3, 범주화 2, 삭제 2',
        processedCount: 0,
        errorCount: 0,
      },
    },
    {
      id: 'LOG_20260410_003',
      time: '2026-04-10 14:10:30',
      operator: '김철수',
      operatorId: 'user_12345',
      action: '규칙설정',
      targetData: 'customer_2024',
      result: '성공',
      resultType: '성공',
      ip: '192.168.1.100',
      browser: 'Chrome 123.0',
      detail: { dataCount: 15240, rulesApplied: '7개 규칙 적용', processedCount: 0, errorCount: 0 },
    },
  ],
  '002': [
    {
      id: 'LOG_20260410_004',
      time: '2026-04-10 14:15:22',
      operator: '이영희',
      operatorId: 'user_23456',
      action: '처리시작',
      targetData: 'transaction_04',
      result: '진행중 (82%)',
      resultType: '진행중',
      ip: '192.168.1.101',
      browser: 'Firefox 124.0',
      detail: {
        dataCount: 8920,
        rulesApplied: '마스킹 2, 암호화 1, 삭제 3',
        processedCount: 7314,
        errorCount: 0,
      },
    },
  ],
  '003': [
    {
      id: 'LOG_20260410_005',
      time: '2026-04-10 13:45:30',
      operator: '박민준',
      operatorId: 'user_34567',
      action: '규칙수정',
      targetData: 'employee_info',
      result: '성공',
      resultType: '성공',
      ip: '192.168.1.102',
      browser: 'Chrome 123.0',
      detail: {
        dataCount: 3200,
        rulesApplied: '마스킹 4, 가명처리 1',
        processedCount: 0,
        errorCount: 0,
      },
    },
  ],
  '004': [
    {
      id: 'LOG_20260409_001',
      time: '2026-04-09 13:45:30',
      operator: '관리자',
      operatorId: 'user_admin',
      action: '처리오류',
      targetData: 'vendor_data',
      result: '오류 (45%)',
      resultType: '실패',
      ip: '192.168.1.100',
      browser: 'Chrome 123.0',
      detail: {
        dataCount: 5100,
        rulesApplied: '마스킹 2, 범주화 1, 삭제 1',
        processedCount: 2295,
        errorCount: 12,
      },
    },
    {
      id: 'LOG_20260409_002',
      time: '2026-04-09 13:40:15',
      operator: '김철수',
      operatorId: 'user_12345',
      action: '규칙조회',
      targetData: 'vendor_data',
      result: '성공',
      resultType: '성공',
      ip: '192.168.1.100',
      browser: 'Chrome 123.0',
      detail: { dataCount: 5100, rulesApplied: '4개 규칙', processedCount: 0, errorCount: 0 },
    },
    {
      id: 'LOG_20260409_003',
      time: '2026-04-09 09:25:00',
      operator: '이영희',
      operatorId: 'user_23456',
      action: '삭제시도',
      targetData: 'vendor_data',
      result: '거부 (권한부족)',
      resultType: '거부',
      ip: '192.168.1.101',
      browser: 'Firefox 124.0',
      detail: { dataCount: 5100, rulesApplied: '-', processedCount: 0, errorCount: 0 },
    },
  ],
  '005': [
    {
      id: 'LOG_20260408_001',
      time: '2026-04-08 09:15:00',
      operator: '박담당',
      operatorId: 'user_45678',
      action: '처리완료',
      targetData: 'partner_contacts',
      result: '성공 (100%)',
      resultType: '성공',
      ip: '192.168.1.103',
      browser: 'Edge 122.0',
      detail: {
        dataCount: 1850,
        rulesApplied: '마스킹 2, 유지 3',
        processedCount: 1850,
        errorCount: 0,
      },
    },
  ],
};

function fetchTasks(): Promise<DeidentifyTask[]> {
  return new Promise((resolve) => {
    setTimeout(() => resolve(MOCK_TASKS), 300);
  });
}

// ─── 상태 뱃지 ─────────────────────────────────────────────

function getStatusBadgeClass(status: TaskStatus): string {
  switch (status) {
    case '완료':
      return 'text-emerald-400 bg-emerald-500/10';
    case '진행중':
      return 'text-cyan-400 bg-cyan-500/10';
    case '대기':
      return 'text-yellow-400 bg-yellow-500/10';
    case '오류':
      return 'text-red-400 bg-red-500/10';
  }
}

// ─── 진행률 바 ─────────────────────────────────────────────

function ProgressBar({ value }: { value: number }) {
  const colorClass =
    value === 100 ? 'bg-emerald-500' : value > 0 ? 'bg-cyan-500' : 'bg-bg-elevated';
  return (
    <div className="flex items-center gap-2">
      <div className="flex-1 h-1.5 bg-bg-elevated rounded-full overflow-hidden">
        <div
          className={`h-full rounded-full transition-all ${colorClass}`}
          style={{ width: `${value}%` }}
        />
      </div>
      <span className="text-t3 w-8 text-right">{value}%</span>
    </div>
  );
}

// ─── 작업 테이블 ────────────────────────────────────────────

const TABLE_HEADERS = ['작업ID', '작업명', '대상', '상태', '시작시간', '진행률', '등록자', '액션'];

interface TaskTableProps {
  rows: DeidentifyTask[];
  loading: boolean;
  onAction: (action: string, task: DeidentifyTask) => void;
}

function TaskTable({ rows, loading, onAction }: TaskTableProps) {
  return (
    <div className="overflow-auto">
      <table className="w-full text-xs border-collapse">
        <thead>
          <tr className="bg-bg-elevated text-t3 uppercase tracking-wide">
            {TABLE_HEADERS.map((h) => (
              <th
                key={h}
                className="px-3 py-2 text-left font-medium border-b border-stroke-1 whitespace-nowrap"
              >
                {h}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {loading && rows.length === 0
            ? Array.from({ length: 5 }).map((_, i) => (
                <tr key={i} className="border-b border-stroke-1 animate-pulse">
                  {TABLE_HEADERS.map((_, j) => (
                    <td key={j} className="px-3 py-2">
                      <div className="h-3 bg-bg-elevated rounded w-14" />
                    </td>
                  ))}
                </tr>
              ))
            : rows.map((row) => (
                <tr key={row.id} className="border-b border-stroke-1 hover:bg-bg-surface/50">
                  <td className="px-3 py-2 text-t3 font-mono">{row.id}</td>
                  <td className="px-3 py-2 font-medium text-t1 whitespace-nowrap">{row.name}</td>
                  <td
                    className="px-3 py-2 text-t2 whitespace-nowrap max-w-[240px] truncate"
                    title={row.target}
                  >
                    {row.target}
                  </td>
                  <td className="px-3 py-2">
                    <span
                      className={`inline-block px-2 py-0.5 rounded text-label-2 font-medium ${getStatusBadgeClass(row.status)}`}
                    >
                      {row.status}
                    </span>
                  </td>
                  <td className="px-3 py-2 text-t2 whitespace-nowrap">{row.startTime}</td>
                  <td className="px-3 py-2 min-w-[120px]">
                    <ProgressBar value={row.progress} />
                  </td>
                  <td className="px-3 py-2 text-t2">{row.createdBy}</td>
                  <td className="px-3 py-2">
                    <div className="flex items-center gap-1 flex-wrap">
                      <button
                        onClick={() => onAction('detail', row)}
                        className="px-2 py-0.5 text-label-2 rounded bg-bg-elevated hover:bg-bg-card text-t2 transition-colors whitespace-nowrap"
                      >
                        상세보기
                      </button>
                      <button
                        onClick={() => onAction('download', row)}
                        className="px-2 py-0.5 text-label-2 rounded bg-bg-elevated hover:bg-bg-card text-t2 transition-colors whitespace-nowrap"
                      >
                        결과다운로드
                      </button>
                      <button
                        onClick={() => onAction('retry', row)}
                        className="px-2 py-0.5 text-label-2 rounded bg-bg-elevated hover:bg-bg-card text-t2 transition-colors whitespace-nowrap"
                      >
                        재실행
                      </button>
                      <button
                        onClick={() => onAction('delete', row)}
                        className="px-2 py-0.5 text-label-2 rounded bg-bg-elevated hover:bg-bg-card text-red-400 transition-colors whitespace-nowrap"
                      >
                        삭제
                      </button>
                      <button
                        onClick={() => onAction('audit', row)}
                        className="px-2 py-0.5 text-label-2 rounded bg-bg-elevated hover:bg-bg-card text-t2 transition-colors whitespace-nowrap"
                      >
                        감사로그
                      </button>
                    </div>
                  </td>
                </tr>
              ))}
        </tbody>
      </table>
    </div>
  );
}

// ─── 마법사: 단계 표시기 ────────────────────────────────────

const STEP_LABELS = ['소스선택', '데이터검증', '비식별화규칙', '처리방식', '최종확인'];

function StepIndicator({ current }: { current: number }) {
  return (
    <div className="flex items-center justify-center gap-0 px-6 py-4 border-b border-stroke-1">
      {STEP_LABELS.map((label, i) => {
        const stepNum = i + 1;
        const isDone = stepNum < current;
        const isActive = stepNum === current;
        return (
          <div key={label} className="flex items-center">
            <div className="flex flex-col items-center">
              <div
                className={`w-7 h-7 rounded-full flex items-center justify-center text-xs font-semibold transition-colors ${
                  isDone
                    ? 'bg-emerald-500 text-white'
                    : isActive
                      ? 'bg-cyan-500 text-white'
                      : 'bg-bg-elevated text-t3'
                }`}
              >
                {isDone ? (
                  <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                    <path
                      strokeLinecap="round"
                      strokeLinejoin="round"
                      strokeWidth={2.5}
                      d="M5 13l4 4L19 7"
                    />
                  </svg>
                ) : (
                  stepNum
                )}
              </div>
              <span
                className={`mt-1 text-label-2 whitespace-nowrap ${
                  isActive ? 'text-cyan-400' : isDone ? 'text-emerald-400' : 'text-t3'
                }`}
              >
                {stepNum}.{label}
              </span>
            </div>
            {i < STEP_LABELS.length - 1 && (
              <div
                className={`w-10 h-px mx-1 mb-4 ${i + 1 < current ? 'bg-emerald-500' : 'bg-stroke-1'}`}
              />
            )}
          </div>
        );
      })}
    </div>
  );
}

// ─── 마법사: Step 1 ─────────────────────────────────────────

interface Step1Props {
  wizard: WizardState;
  onChange: (patch: Partial<WizardState>) => void;
}

function Step1({ wizard, onChange }: Step1Props) {
  const handleDbChange = (key: keyof DbConfig, value: string) => {
    onChange({ dbConfig: { ...wizard.dbConfig, [key]: value } });
  };
  const handleApiChange = (key: keyof ApiConfig, value: string) => {
    onChange({ apiConfig: { ...wizard.apiConfig, [key]: value } });
  };

  return (
    <div className="space-y-5">
      <div>
        <label className="block text-xs font-medium text-t2 mb-1">작업명 *</label>
        <input
          type="text"
          value={wizard.taskName}
          onChange={(e) => onChange({ taskName: e.target.value })}
          placeholder="작업 이름을 입력하세요"
          className="w-full px-3 py-2 text-xs rounded bg-bg-elevated border border-stroke-1 text-t1 placeholder:text-t3 focus:outline-none focus:border-cyan-500"
        />
      </div>

      <div>
        <label className="block text-xs font-medium text-t2 mb-2">소스 유형 *</label>
        <div className="flex flex-col gap-2">
          {(
            [
              ['db', '데이터베이스 연결'],
              ['file', '파일 업로드'],
              ['api', 'API 호출'],
            ] as [SourceType, string][]
          ).map(([val, label]) => (
            <label key={val} className="flex items-center gap-2 cursor-pointer">
              <input
                type="radio"
                name="sourceType"
                value={val}
                checked={wizard.sourceType === val}
                onChange={() => onChange({ sourceType: val })}
                className="accent-cyan-500"
              />
              <span className="text-xs text-t1">{label}</span>
            </label>
          ))}
        </div>
      </div>

      {wizard.sourceType === 'db' && (
        <div className="grid grid-cols-2 gap-3 p-4 rounded bg-bg-surface border border-stroke-1">
          {(
            [
              ['host', '호스트', 'localhost'],
              ['port', '포트', '5432'],
              ['database', '데이터베이스', 'wing'],
              ['tableName', '테이블명', 'public.customers'],
            ] as [keyof DbConfig, string, string][]
          ).map(([key, labelText, placeholder]) => (
            <div key={key}>
              <label className="block text-label-2 text-t3 mb-1">{labelText}</label>
              <input
                type="text"
                value={wizard.dbConfig[key]}
                onChange={(e) => handleDbChange(key, e.target.value)}
                placeholder={placeholder}
                className="w-full px-2.5 py-1.5 text-xs rounded bg-bg-elevated border border-stroke-1 text-t1 placeholder:text-t3 focus:outline-none focus:border-cyan-500"
              />
            </div>
          ))}
        </div>
      )}

      {wizard.sourceType === 'file' && (
        <div className="p-8 rounded border-2 border-dashed border-stroke-1 bg-bg-surface flex flex-col items-center gap-2 text-center">
          <svg className="w-8 h-8 text-t3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path
              strokeLinecap="round"
              strokeLinejoin="round"
              strokeWidth={1.5}
              d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
            />
          </svg>
          <p className="text-xs text-t2">파일을 드래그하거나 클릭하여 업로드</p>
          <p className="text-label-2 text-t3">CSV, XLSX, JSON 지원 (최대 500MB)</p>
        </div>
      )}

      {wizard.sourceType === 'api' && (
        <div className="p-4 rounded bg-bg-surface border border-stroke-1 space-y-3">
          <div>
            <label className="block text-label-2 text-t3 mb-1">API URL</label>
            <input
              type="text"
              value={wizard.apiConfig.url}
              onChange={(e) => handleApiChange('url', e.target.value)}
              placeholder="https://api.example.com/data"
              className="w-full px-2.5 py-1.5 text-xs rounded bg-bg-elevated border border-stroke-1 text-t1 placeholder:text-t3 focus:outline-none focus:border-cyan-500"
            />
          </div>
          <div>
            <label className="block text-label-2 text-t3 mb-1">메서드</label>
            <select
              value={wizard.apiConfig.method}
              onChange={(e) => handleApiChange('method', e.target.value)}
              className="px-2.5 py-1.5 text-xs rounded bg-bg-elevated border border-stroke-1 text-t1 focus:outline-none focus:border-cyan-500"
            >
              <option value="GET">GET</option>
              <option value="POST">POST</option>
            </select>
          </div>
        </div>
      )}
    </div>
  );
}

// ─── 마법사: Step 2 ─────────────────────────────────────────

interface Step2Props {
  wizard: WizardState;
  onChange: (patch: Partial<WizardState>) => void;
}

function Step2({ wizard, onChange }: Step2Props) {
  const toggleField = (idx: number) => {
    const updated = wizard.fields.map((f, i) => (i === idx ? { ...f, selected: !f.selected } : f));
    onChange({ fields: updated });
  };

  return (
    <div className="space-y-4">
      <div className="grid grid-cols-3 gap-3">
        {[
          { label: '총 데이터 건수', value: '15,240건', color: 'text-t1' },
          { label: '중복', value: '0건', color: 'text-emerald-400' },
          { label: '누락값', value: '23건', color: 'text-yellow-400' },
        ].map((stat) => (
          <div key={stat.label} className="p-3 rounded bg-bg-surface border border-stroke-1">
            <p className="text-label-2 text-t3 mb-1">{stat.label}</p>
            <p className={`text-sm font-semibold ${stat.color}`}>{stat.value}</p>
          </div>
        ))}
      </div>

      <div>
        <h4 className="text-xs font-medium text-t2 mb-2">스키마 분석 결과 — 포함 필드 선택</h4>
        <div className="rounded border border-stroke-1 overflow-hidden">
          <table className="w-full text-xs border-collapse">
            <thead>
              <tr className="bg-bg-elevated text-t3">
                <th className="px-3 py-2 text-left font-medium border-b border-stroke-1 w-8">
                  <input
                    type="checkbox"
                    checked={wizard.fields.every((f) => f.selected)}
                    onChange={(e) =>
                      onChange({
                        fields: wizard.fields.map((f) => ({ ...f, selected: e.target.checked })),
                      })
                    }
                    className="accent-cyan-500"
                  />
                </th>
                <th className="px-3 py-2 text-left font-medium border-b border-stroke-1">필드명</th>
                <th className="px-3 py-2 text-left font-medium border-b border-stroke-1">
                  데이터 타입
                </th>
              </tr>
            </thead>
            <tbody>
              {wizard.fields.map((field, idx) => (
                <tr key={field.name} className="border-b border-stroke-1 hover:bg-bg-surface/50">
                  <td className="px-3 py-2">
                    <input
                      type="checkbox"
                      checked={field.selected}
                      onChange={() => toggleField(idx)}
                      className="accent-cyan-500"
                    />
                  </td>
                  <td className="px-3 py-2 font-medium text-t1">{field.name}</td>
                  <td className="px-3 py-2 text-t3">{field.dataType}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
        <p className="mt-1.5 text-label-2 text-t3">
          {wizard.fields.filter((f) => f.selected).length}개 선택됨 (전체 {wizard.fields.length}개)
        </p>
      </div>
    </div>
  );
}

// ─── 마법사: Step 3 ─────────────────────────────────────────

interface Step3Props {
  wizard: WizardState;
  onChange: (patch: Partial<WizardState>) => void;
}

function Step3({ wizard, onChange }: Step3Props) {
  const updateField = (idx: number, key: keyof FieldConfig, value: string | boolean) => {
    const updated = wizard.fields.map((f, i) => (i === idx ? { ...f, [key]: value } : f));
    onChange({ fields: updated });
  };

  const selectedFields = wizard.fields.filter((f) => f.selected);

  return (
    <div className="space-y-4">
      <div className="rounded border border-stroke-1 overflow-hidden">
        <table className="w-full text-xs border-collapse">
          <thead>
            <tr className="bg-bg-elevated text-t3">
              <th className="px-3 py-2 text-left font-medium border-b border-stroke-1">필드명</th>
              <th className="px-3 py-2 text-left font-medium border-b border-stroke-1">
                데이터타입
              </th>
              <th className="px-3 py-2 text-left font-medium border-b border-stroke-1">
                선택된 기법
              </th>
              <th className="px-3 py-2 text-left font-medium border-b border-stroke-1">설정값</th>
            </tr>
          </thead>
          <tbody>
            {selectedFields.map((field) => {
              const globalIdx = wizard.fields.findIndex((f) => f.name === field.name);
              return (
                <tr key={field.name} className="border-b border-stroke-1 hover:bg-bg-surface/50">
                  <td className="px-3 py-2 font-medium text-t1">{field.name}</td>
                  <td className="px-3 py-2 text-t3">{field.dataType}</td>
                  <td className="px-3 py-2">
                    <select
                      value={field.technique}
                      onChange={(e) => updateField(globalIdx, 'technique', e.target.value)}
                      className="px-2 py-1 text-xs rounded bg-bg-elevated border border-stroke-1 text-t1 focus:outline-none focus:border-cyan-500"
                    >
                      {TECHNIQUES.map((t) => (
                        <option key={t} value={t}>
                          {t}
                        </option>
                      ))}
                    </select>
                  </td>
                  <td className="px-3 py-2">
                    <input
                      type="text"
                      value={field.configValue}
                      onChange={(e) => updateField(globalIdx, 'configValue', e.target.value)}
                      className="w-full px-2 py-1 text-xs rounded bg-bg-elevated border border-stroke-1 text-t1 focus:outline-none focus:border-cyan-500"
                    />
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>

      <div className="flex flex-wrap items-center gap-4 pt-1">
        <label className="flex items-center gap-2 cursor-pointer">
          <input
            type="checkbox"
            checked={wizard.saveAsTemplate}
            onChange={(e) => onChange({ saveAsTemplate: e.target.checked })}
            className="accent-cyan-500"
          />
          <span className="text-xs text-t2">템플릿으로 저장</span>
        </label>

        <div className="flex items-center gap-2">
          <span className="text-xs text-t3">이전 템플릿 적용:</span>
          <select
            value={wizard.applyTemplate}
            onChange={(e) => onChange({ applyTemplate: e.target.value })}
            className="px-2.5 py-1 text-xs rounded bg-bg-elevated border border-stroke-1 text-t1 focus:outline-none focus:border-cyan-500"
          >
            <option value="">선택 안 함</option>
            {TEMPLATES.map((t) => (
              <option key={t} value={t}>
                {t}
              </option>
            ))}
          </select>
        </div>
      </div>
    </div>
  );
}

// ─── 마법사: Step 4 ─────────────────────────────────────────

interface Step4Props {
  wizard: WizardState;
  onChange: (patch: Partial<WizardState>) => void;
}

function Step4({ wizard, onChange }: Step4Props) {
  const handleScheduleChange = (key: keyof ScheduleConfig, value: string | boolean) => {
    onChange({ scheduleConfig: { ...wizard.scheduleConfig, [key]: value } });
  };
  const handleOneshotChange = (key: keyof OneshotConfig, value: string) => {
    onChange({ oneshotConfig: { ...wizard.oneshotConfig, [key]: value } });
  };

  return (
    <div className="space-y-4">
      <div className="space-y-3">
        {(
          [
            ['immediate', '즉시 처리', '지금 바로 데이터를 비식별화합니다.'],
            ['scheduled', '배치 처리 - 정기 스케줄링', '반복 일정에 따라 자동으로 처리합니다.'],
            ['oneshot', '배치 처리 - 일회성', '지정한 날짜/시간에 한 번 처리합니다.'],
          ] as [ProcessMode, string, string][]
        ).map(([val, label, desc]) => (
          <div key={val}>
            <label className="flex items-start gap-2.5 cursor-pointer">
              <input
                type="radio"
                name="processMode"
                value={val}
                checked={wizard.processMode === val}
                onChange={() => onChange({ processMode: val })}
                className="mt-0.5 accent-cyan-500"
              />
              <div>
                <span className="text-xs font-medium text-t1">{label}</span>
                <p className="text-label-2 text-t3 mt-0.5">{desc}</p>
              </div>
            </label>

            {val === 'scheduled' && wizard.processMode === 'scheduled' && (
              <div className="mt-3 ml-5 p-4 rounded bg-bg-surface border border-stroke-1 space-y-3">
                <div className="flex items-center gap-3">
                  <label className="text-xs text-t3 w-16 shrink-0">실행 시간</label>
                  <select
                    value={wizard.scheduleConfig.hour}
                    onChange={(e) => handleScheduleChange('hour', e.target.value)}
                    className="px-2.5 py-1.5 text-xs rounded bg-bg-elevated border border-stroke-1 text-t1 focus:outline-none focus:border-cyan-500"
                  >
                    {HOURS.map((h) => (
                      <option key={h} value={h}>
                        {h}
                      </option>
                    ))}
                  </select>
                </div>
                <div className="flex items-start gap-3">
                  <label className="text-xs text-t3 w-16 shrink-0 mt-1">반복</label>
                  <div className="flex flex-col gap-2">
                    {(
                      [
                        ['daily', '매일'],
                        ['weekly', '주 1회'],
                        ['monthly', '월 1회'],
                      ] as [RepeatType, string][]
                    ).map(([rt, rl]) => (
                      <div key={rt} className="flex items-center gap-2">
                        <input
                          type="radio"
                          name="repeatType"
                          value={rt}
                          checked={wizard.scheduleConfig.repeatType === rt}
                          onChange={() => handleScheduleChange('repeatType', rt)}
                          className="accent-cyan-500"
                        />
                        <span className="text-xs text-t1">{rl}</span>
                        {rt === 'weekly' && wizard.scheduleConfig.repeatType === 'weekly' && (
                          <select
                            value={wizard.scheduleConfig.weekday}
                            onChange={(e) => handleScheduleChange('weekday', e.target.value)}
                            className="ml-1 px-2 py-0.5 text-xs rounded bg-bg-elevated border border-stroke-1 text-t1 focus:outline-none focus:border-cyan-500"
                          >
                            {WEEKDAYS.map((d) => (
                              <option key={d} value={d}>
                                {d}요일
                              </option>
                            ))}
                          </select>
                        )}
                      </div>
                    ))}
                  </div>
                </div>
                <div className="flex items-center gap-3">
                  <label className="text-xs text-t3 w-16 shrink-0">시작일</label>
                  <input
                    type="date"
                    value={wizard.scheduleConfig.startDate}
                    onChange={(e) => handleScheduleChange('startDate', e.target.value)}
                    className="px-2.5 py-1.5 text-xs rounded bg-bg-elevated border border-stroke-1 text-t1 focus:outline-none focus:border-cyan-500"
                  />
                </div>
                <div className="flex flex-col gap-1.5 mt-1">
                  <label className="flex items-center gap-2 cursor-pointer">
                    <input
                      type="checkbox"
                      checked={wizard.scheduleConfig.notifyOnComplete}
                      onChange={(e) => handleScheduleChange('notifyOnComplete', e.target.checked)}
                      className="accent-cyan-500"
                    />
                    <span className="text-xs text-t2">처리 완료 시 이메일 알림</span>
                  </label>
                  <label className="flex items-center gap-2 cursor-pointer">
                    <input
                      type="checkbox"
                      checked={wizard.scheduleConfig.notifyOnError}
                      onChange={(e) => handleScheduleChange('notifyOnError', e.target.checked)}
                      className="accent-cyan-500"
                    />
                    <span className="text-xs text-t2">오류 발생 시 즉시 알림</span>
                  </label>
                </div>
              </div>
            )}

            {val === 'oneshot' && wizard.processMode === 'oneshot' && (
              <div className="mt-3 ml-5 p-4 rounded bg-bg-surface border border-stroke-1 space-y-3">
                <div className="flex items-center gap-3">
                  <label className="text-xs text-t3 w-16 shrink-0">실행 날짜</label>
                  <input
                    type="date"
                    value={wizard.oneshotConfig.date}
                    onChange={(e) => handleOneshotChange('date', e.target.value)}
                    className="px-2.5 py-1.5 text-xs rounded bg-bg-elevated border border-stroke-1 text-t1 focus:outline-none focus:border-cyan-500"
                  />
                </div>
                <div className="flex items-center gap-3">
                  <label className="text-xs text-t3 w-16 shrink-0">실행 시간</label>
                  <select
                    value={wizard.oneshotConfig.hour}
                    onChange={(e) => handleOneshotChange('hour', e.target.value)}
                    className="px-2.5 py-1.5 text-xs rounded bg-bg-elevated border border-stroke-1 text-t1 focus:outline-none focus:border-cyan-500"
                  >
                    {HOURS.map((h) => (
                      <option key={h} value={h}>
                        {h}
                      </option>
                    ))}
                  </select>
                </div>
              </div>
            )}
          </div>
        ))}
      </div>
    </div>
  );
}

// ─── 마법사: Step 5 ─────────────────────────────────────────

interface Step5Props {
  wizard: WizardState;
  onChange: (patch: Partial<WizardState>) => void;
}

function Step5({ wizard, onChange }: Step5Props) {
  const selectedCount = wizard.fields.filter((f) => f.selected).length;
  const ruleCount = wizard.fields.filter((f) => f.selected && f.technique !== '유지').length;

  const processModeLabel: Record<ProcessMode, string> = {
    immediate: '즉시 처리',
    scheduled: `배치 - 정기 (${wizard.scheduleConfig.hour} / ${wizard.scheduleConfig.repeatType === 'daily' ? '매일' : wizard.scheduleConfig.repeatType === 'weekly' ? `주1회 ${wizard.scheduleConfig.weekday}요일` : '월1회'})`,
    oneshot: `배치 - 일회성 (${wizard.oneshotConfig.date} ${wizard.oneshotConfig.hour})`,
  };

  const summaryRows = [
    { label: '작업명', value: wizard.taskName || '(미입력)' },
    {
      label: '소스',
      value:
        wizard.sourceType === 'db'
          ? `DB: ${wizard.dbConfig.database}.${wizard.dbConfig.tableName}`
          : wizard.sourceType === 'file'
            ? '파일 업로드'
            : `API: ${wizard.apiConfig.url}`,
    },
    { label: '데이터 건수', value: '15,240건' },
    { label: '선택 필드 수', value: `${selectedCount}개` },
    { label: '비식별화 규칙 수', value: `${ruleCount}개` },
    { label: '처리 방식', value: processModeLabel[wizard.processMode] },
    { label: '예상 처리시간', value: '약 3~5분' },
  ];

  return (
    <div className="space-y-4">
      <div className="rounded border border-stroke-1 overflow-hidden">
        <table className="w-full text-xs border-collapse">
          <tbody>
            {summaryRows.map(({ label, value }) => (
              <tr key={label} className="border-b border-stroke-1 last:border-b-0">
                <td className="px-4 py-2.5 text-t3 bg-bg-elevated w-36 font-medium">{label}</td>
                <td className="px-4 py-2.5 text-t1">{value}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <label className="flex items-center gap-2 cursor-pointer p-3 rounded border border-stroke-1 bg-bg-surface">
        <input
          type="checkbox"
          checked={wizard.confirmed}
          onChange={(e) => onChange({ confirmed: e.target.checked })}
          className="accent-cyan-500"
        />
        <span className="text-xs text-t1 font-medium">위 정보를 확인했습니다.</span>
      </label>
    </div>
  );
}

// ─── 마법사 모달 ─────────────────────────────────────────────

const INITIAL_WIZARD: WizardState = {
  step: 1,
  taskName: '',
  sourceType: 'db',
  dbConfig: { host: '', port: '5432', database: '', tableName: '' },
  apiConfig: { url: '', method: 'GET' },
  fields: DEFAULT_FIELDS,
  processMode: 'immediate',
  scheduleConfig: {
    hour: '02:00',
    repeatType: 'daily',
    weekday: '월',
    startDate: '',
    notifyOnComplete: true,
    notifyOnError: true,
  },
  oneshotConfig: { date: '', hour: '02:00' },
  saveAsTemplate: false,
  applyTemplate: '',
  confirmed: false,
};

// ─── 감사로그 모달 ─────────────────────────────────────────

function getAuditResultClass(type: AuditLogEntry['resultType']): string {
  switch (type) {
    case '성공':
      return 'text-emerald-400 bg-emerald-500/10';
    case '진행중':
      return 'text-cyan-400 bg-cyan-500/10';
    case '실패':
      return 'text-red-400 bg-red-500/10';
    case '거부':
      return 'text-yellow-400 bg-yellow-500/10';
  }
}

interface AuditLogModalProps {
  task: DeidentifyTask;
  onClose: () => void;
}

function AuditLogModal({ task, onClose }: AuditLogModalProps) {
  const logs = MOCK_AUDIT_LOGS[task.id] ?? [];
  const [selectedLog, setSelectedLog] = useState<AuditLogEntry | null>(null);
  const [filterOperator, setFilterOperator] = useState('모두');
  const [startDate, setStartDate] = useState('2026-04-01');
  const [endDate, setEndDate] = useState('2026-04-11');

  const operators = ['모두', ...Array.from(new Set(logs.map((l) => l.operator)))];
  const filteredLogs = logs.filter((l) => {
    if (filterOperator !== '모두' && l.operator !== filterOperator) return false;
    return true;
  });

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60">
      <div className="bg-bg-card border border-stroke-1 rounded-lg shadow-2xl w-full max-w-5xl max-h-[85vh] flex flex-col">
        {/* 헤더 */}
        <div className="flex items-center justify-between px-5 py-3 border-b border-stroke-1 shrink-0">
          <h3 className="text-sm font-semibold text-t1">감시 감독 (감사로그) — {task.name}</h3>
          <button
            onClick={onClose}
            className="text-t3 hover:text-t1 transition-colors text-lg leading-none"
          >
            ✕
          </button>
        </div>

        {/* 필터 바 */}
        <div className="flex items-center gap-3 px-5 py-2.5 border-b border-stroke-1 shrink-0 bg-bg-base">
          <span className="text-xs text-t3">기간:</span>
          <input
            type="date"
            value={startDate}
            onChange={(e) => setStartDate(e.target.value)}
            className="px-2 py-1 text-xs rounded bg-bg-elevated border border-stroke-1 text-t1 focus:outline-none focus:border-cyan-500"
          />
          <span className="text-xs text-t3">~</span>
          <input
            type="date"
            value={endDate}
            onChange={(e) => setEndDate(e.target.value)}
            className="px-2 py-1 text-xs rounded bg-bg-elevated border border-stroke-1 text-t1 focus:outline-none focus:border-cyan-500"
          />
          <span className="text-xs text-t3 ml-2">작업자:</span>
          <select
            value={filterOperator}
            onChange={(e) => setFilterOperator(e.target.value)}
            className="px-2 py-1 text-xs rounded bg-bg-elevated border border-stroke-1 text-t1 focus:outline-none focus:border-cyan-500"
          >
            {operators.map((op) => (
              <option key={op} value={op}>
                {op}
              </option>
            ))}
          </select>
        </div>

        {/* 로그 테이블 */}
        <div className="flex-1 overflow-auto px-5 py-3">
          <table className="w-full text-xs border-collapse">
            <thead>
              <tr className="bg-bg-elevated text-t3 uppercase tracking-wide">
                {['시간', '작업자', '작업', '대상 데이터', '결과', '상세'].map((h) => (
                  <th
                    key={h}
                    className="px-3 py-2 text-left font-medium border-b border-stroke-1 whitespace-nowrap"
                  >
                    {h}
                  </th>
                ))}
              </tr>
            </thead>
            <tbody>
              {filteredLogs.length === 0 ? (
                <tr>
                  <td colSpan={6} className="px-3 py-8 text-center text-t3">
                    감사로그가 없습니다.
                  </td>
                </tr>
              ) : (
                filteredLogs.map((log) => (
                  <tr
                    key={log.id}
                    className={`border-b border-stroke-1 hover:bg-bg-surface/50 cursor-pointer ${selectedLog?.id === log.id ? 'bg-bg-surface/70' : ''}`}
                    onClick={() => setSelectedLog(log)}
                  >
                    <td className="px-3 py-2 text-t2 whitespace-nowrap font-mono">
                      {log.time.split(' ')[1]}
                    </td>
                    <td className="px-3 py-2 text-t1 whitespace-nowrap">{log.operator}</td>
                    <td className="px-3 py-2 text-t2 whitespace-nowrap">{log.action}</td>
                    <td className="px-3 py-2 text-t2 whitespace-nowrap font-mono">
                      {log.targetData}
                    </td>
                    <td className="px-3 py-2">
                      <span
                        className={`inline-block px-2 py-0.5 rounded text-label-2 font-medium ${getAuditResultClass(log.resultType)}`}
                      >
                        {log.result}
                      </span>
                    </td>
                    <td className="px-3 py-2">
                      <button
                        onClick={(e) => {
                          e.stopPropagation();
                          setSelectedLog(log);
                        }}
                        className="px-2 py-0.5 text-label-2 rounded bg-bg-elevated hover:bg-bg-card text-cyan-400 transition-colors whitespace-nowrap"
                      >
                        보기
                      </button>
                    </td>
                  </tr>
                ))
              )}
            </tbody>
          </table>
        </div>

        {/* 로그 상세 정보 */}
        {selectedLog && (
          <div className="px-5 py-3 border-t border-stroke-1 shrink-0 bg-bg-base">
            <h4 className="text-xs font-semibold text-t1 mb-2">로그 상세 정보</h4>
            <div className="bg-bg-elevated border border-stroke-1 rounded p-3 text-xs grid grid-cols-2 gap-x-6 gap-y-1.5">
              <div>
                <span className="text-t3">로그ID:</span>{' '}
                <span className="text-t1 font-mono">{selectedLog.id}</span>
              </div>
              <div>
                <span className="text-t3">타임스탬프:</span>{' '}
                <span className="text-t1 font-mono">{selectedLog.time}</span>
              </div>
              <div>
                <span className="text-t3">작업자:</span>{' '}
                <span className="text-t1">
                  {selectedLog.operator} ({selectedLog.operatorId})
                </span>
              </div>
              <div>
                <span className="text-t3">작업 유형:</span>{' '}
                <span className="text-t1">{selectedLog.action}</span>
              </div>
              <div>
                <span className="text-t3">대상:</span>{' '}
                <span className="text-t1">
                  {selectedLog.targetData} ({selectedLog.detail.dataCount.toLocaleString()}건)
                </span>
              </div>
              <div>
                <span className="text-t3">적용 규칙:</span>{' '}
                <span className="text-t1">{selectedLog.detail.rulesApplied}</span>
              </div>
              <div>
                <span className="text-t3">결과:</span>{' '}
                <span className="text-t1">
                  {selectedLog.result} (처리: {selectedLog.detail.processedCount.toLocaleString()},
                  오류: {selectedLog.detail.errorCount})
                </span>
              </div>
              <div>
                <span className="text-t3">IP 주소:</span>{' '}
                <span className="text-t1 font-mono">{selectedLog.ip}</span>
              </div>
              <div>
                <span className="text-t3">브라우저:</span>{' '}
                <span className="text-t1">{selectedLog.browser}</span>
              </div>
            </div>
          </div>
        )}

        {/* 하단 버튼 */}
        <div className="flex items-center justify-end gap-2 px-5 py-3 border-t border-stroke-1 shrink-0">
          <button className="px-3 py-1.5 text-xs rounded bg-bg-elevated hover:bg-bg-card text-t2 transition-colors">
            상세내용 다운로드 (암호화됨)
          </button>
          <button className="px-3 py-1.5 text-xs rounded bg-bg-elevated hover:bg-bg-card text-t2 transition-colors">
            기간별 보고서 생성
          </button>
          <button
            onClick={onClose}
            className="px-3 py-1.5 text-xs rounded bg-bg-elevated hover:bg-bg-card text-t2 transition-colors"
          >
            닫기
          </button>
        </div>
      </div>
    </div>
  );
}

// ─── 마법사 모달 ───────────────────────────────────────────

interface WizardModalProps {
  onClose: () => void;
  onSubmit: (wizard: WizardState) => void;
}

function WizardModal({ onClose, onSubmit }: WizardModalProps) {
  const [wizard, setWizard] = useState<WizardState>(INITIAL_WIZARD);

  const patch = useCallback((update: Partial<WizardState>) => {
    setWizard((prev) => ({ ...prev, ...update }));
  }, []);

  const handleNext = () => {
    if (wizard.step < 5) patch({ step: wizard.step + 1 });
  };
  const handlePrev = () => {
    if (wizard.step > 1) patch({ step: wizard.step - 1 });
  };
  const handleSubmit = () => {
    onSubmit(wizard);
    onClose();
  };

  const canProceed = () => {
    if (wizard.step === 1) return wizard.taskName.trim().length > 0;
    if (wizard.step === 2) return wizard.fields.some((f) => f.selected);
    if (wizard.step === 5) return wizard.confirmed;
    return true;
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60">
      <div className="bg-bg-card border border-stroke-1 rounded-lg shadow-2xl w-full max-w-4xl mx-4 flex flex-col max-h-[90vh]">
        {/* 모달 헤더 */}
        <div className="flex items-center justify-between px-6 py-4 border-b border-stroke-1 shrink-0">
          <h3 className="text-sm font-semibold text-t1">새 비식별화 작업</h3>
          <button
            onClick={onClose}
            className="p-1 rounded text-t3 hover:text-t1 hover:bg-bg-elevated transition-colors"
          >
            <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M6 18L18 6M6 6l12 12"
              />
            </svg>
          </button>
        </div>

        {/* 단계 표시기 */}
        <StepIndicator current={wizard.step} />

        {/* 단계 내용 */}
        <div className="flex-1 overflow-auto px-6 py-5">
          {wizard.step === 1 && <Step1 wizard={wizard} onChange={patch} />}
          {wizard.step === 2 && <Step2 wizard={wizard} onChange={patch} />}
          {wizard.step === 3 && <Step3 wizard={wizard} onChange={patch} />}
          {wizard.step === 4 && <Step4 wizard={wizard} onChange={patch} />}
          {wizard.step === 5 && <Step5 wizard={wizard} onChange={patch} />}
        </div>

        {/* 푸터 버튼 */}
        <div className="flex items-center justify-between px-6 py-4 border-t border-stroke-1 shrink-0">
          <button
            onClick={handlePrev}
            disabled={wizard.step === 1}
            className="px-3 py-1.5 text-xs rounded bg-bg-elevated hover:bg-bg-card text-t2 disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
          >
            이전
          </button>
          <div className="flex items-center gap-2">
            <button
              onClick={onClose}
              className="px-3 py-1.5 text-xs rounded bg-bg-elevated hover:bg-bg-card text-t2 transition-colors"
            >
              취소
            </button>
            {wizard.step < 5 ? (
              <button
                onClick={handleNext}
                disabled={!canProceed()}
                className="px-3 py-1.5 text-xs rounded bg-cyan-600 hover:bg-cyan-700 text-white disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
              >
                다음
              </button>
            ) : (
              <button
                onClick={handleSubmit}
                disabled={!canProceed()}
                className="px-3 py-1.5 text-xs rounded bg-cyan-600 hover:bg-cyan-700 text-white disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
              >
                처리 시작
              </button>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

// ─── 메인 패널 ──────────────────────────────────────────────

type FilterStatus = '모두' | TaskStatus;

export default function DeidentifyPanel() {
  const [tasks, setTasks] = useState<DeidentifyTask[]>([]);
  const [loading, setLoading] = useState(false);
  const [showWizard, setShowWizard] = useState(false);
  const [auditTask, setAuditTask] = useState<DeidentifyTask | null>(null);
  const [searchName, setSearchName] = useState('');
  const [filterStatus, setFilterStatus] = useState<FilterStatus>('모두');
  const [filterPeriod, setFilterPeriod] = useState<'7' | '30' | '90'>('30');

  const loadTasks = useCallback(async () => {
    setLoading(true);
    const data = await fetchTasks();
    setTasks(data);
    setLoading(false);
  }, []);

  useEffect(() => {
    let isMounted = true;
    if (tasks.length === 0) {
      void Promise.resolve().then(() => {
        if (isMounted) void loadTasks();
      });
    }
    return () => {
      isMounted = false;
    };
  }, [tasks.length, loadTasks]);

  const handleAction = useCallback((action: string, task: DeidentifyTask) => {
    // TODO: 실제 API 연동 시 각 액션에 맞는 API 호출로 교체
    if (action === 'delete') {
      setTasks((prev) => prev.filter((t) => t.id !== task.id));
    } else if (action === 'audit') {
      setAuditTask(task);
    }
  }, []);

  const handleWizardSubmit = useCallback(
    (wizard: WizardState) => {
      const selectedFields = wizard.fields.filter((f) => f.selected).map((f) => f.name);
      const newTask: DeidentifyTask = {
        id: String(tasks.length + 1).padStart(3, '0'),
        name: wizard.taskName,
        target: selectedFields.join(', ') || '-',
        status: wizard.processMode === 'immediate' ? '진행중' : '대기',
        startTime: new Date()
          .toLocaleString('ko-KR', {
            year: 'numeric',
            month: '2-digit',
            day: '2-digit',
            hour: '2-digit',
            minute: '2-digit',
            hour12: false,
          })
          .replace(/\. /g, '-')
          .replace('.', ''),
        progress: 0,
        createdBy: '관리자',
      };
      setTasks((prev) => [newTask, ...prev]);
    },
    [tasks.length],
  );

  const filteredTasks = tasks.filter((t) => {
    if (searchName && !t.name.includes(searchName)) return false;
    if (filterStatus !== '모두' && t.status !== filterStatus) return false;
    return true;
  });

  const completedCount = tasks.filter((t) => t.status === '완료').length;
  const inProgressCount = tasks.filter((t) => t.status === '진행중').length;
  const errorCount = tasks.filter((t) => t.status === '오류').length;

  return (
    <div className="flex flex-col h-full overflow-hidden">
      {/* 헤더 */}
      <div className="flex items-center justify-between px-5 py-3 border-b border-stroke-1 shrink-0">
        <h2 className="text-sm font-semibold text-t1">비식별화조치</h2>
        <button
          onClick={() => setShowWizard(true)}
          className="flex items-center gap-1.5 px-3 py-1.5 text-xs rounded bg-cyan-600 hover:bg-cyan-700 text-white transition-colors"
        >
          <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
          </svg>
          새 작업
        </button>
      </div>

      {/* 상태 요약 */}
      <div className="flex items-center gap-3 px-5 py-2 shrink-0 border-b border-stroke-1 bg-bg-base">
        <span className="inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs bg-emerald-500/10 text-emerald-400">
          <span className="w-1.5 h-1.5 rounded-full bg-emerald-400" />
          완료 {completedCount}건
        </span>
        <span className="inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs bg-cyan-500/10 text-cyan-400">
          <span className="w-1.5 h-1.5 rounded-full bg-cyan-400" />
          진행중 {inProgressCount}건
        </span>
        {errorCount > 0 && (
          <span className="inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs bg-red-500/10 text-red-400">
            <span className="w-1.5 h-1.5 rounded-full bg-red-400" />
            오류 {errorCount}건
          </span>
        )}
        <span className="text-xs text-t3">전체 {tasks.length}건</span>
      </div>

      {/* 검색/필터 */}
      <div className="flex items-center gap-2 px-5 py-2.5 shrink-0 border-b border-stroke-1">
        <input
          type="text"
          value={searchName}
          onChange={(e) => setSearchName(e.target.value)}
          placeholder="작업명 검색"
          className="px-2.5 py-1.5 text-xs rounded bg-bg-elevated border border-stroke-1 text-t1 placeholder:text-t3 focus:outline-none focus:border-cyan-500 w-40"
        />
        <select
          value={filterStatus}
          onChange={(e) => setFilterStatus(e.target.value as FilterStatus)}
          className="px-2.5 py-1.5 text-xs rounded bg-bg-elevated border border-stroke-1 text-t1 focus:outline-none focus:border-cyan-500"
        >
          {(['모두', '완료', '진행중', '대기', '오류'] as FilterStatus[]).map((s) => (
            <option key={s} value={s}>
              {s}
            </option>
          ))}
        </select>
        <select
          value={filterPeriod}
          onChange={(e) => setFilterPeriod(e.target.value as '7' | '30' | '90')}
          className="px-2.5 py-1.5 text-xs rounded bg-bg-elevated border border-stroke-1 text-t1 focus:outline-none focus:border-cyan-500"
        >
          <option value="7">최근 7일</option>
          <option value="30">최근 30일</option>
          <option value="90">최근 90일</option>
        </select>
      </div>

      {/* 테이블 */}
      <div className="flex-1 overflow-auto p-5">
        <TaskTable rows={filteredTasks} loading={loading} onAction={handleAction} />
      </div>

      {/* 감사로그 모달 */}
      {auditTask && <AuditLogModal task={auditTask} onClose={() => setAuditTask(null)} />}

      {/* 마법사 모달 */}
      {showWizard && (
        <WizardModal onClose={() => setShowWizard(false)} onSubmit={handleWizardSubmit} />
      )}
    </div>
  );
}
