import { useState, useCallback, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import { batchApi } from '../api/batchApi';
import type { JobDetailDto } from '../api/batchApi';
import { usePoller } from '../hooks/usePoller';
import { useToastContext } from '../contexts/ToastContext';
import StatusBadge from '../components/StatusBadge';
import EmptyState from '../components/EmptyState';
import LoadingSpinner from '../components/LoadingSpinner';
import { formatDateTime, calculateDuration } from '../utils/formatters';
import GuideModal, { HelpButton } from '../components/GuideModal';

const POLLING_INTERVAL = 30000;

const JOBS_GUIDE = [
  {
    title: '상태 필터',
    content: '상단의 탭 버튼으로 작업 상태별 필터링이 가능합니다.\n전체 / 실행 중 / 성공 / 실패 / 미실행 중 선택하세요.\n각 탭 옆의 숫자는 해당 상태의 작업 수입니다.',
  },
  {
    title: '검색 및 정렬',
    content: '검색창에 작업명을 입력하면 실시간으로 필터링됩니다.\n정렬 옵션: 작업명순, 최신 실행순(기본), 상태별(실패 우선)\n테이블/카드 뷰 전환 버튼으로 보기 방식을 변경할 수 있습니다.',
  },
  {
    title: '작업 실행',
    content: '"실행" 버튼을 클릭하면 확인 팝업이 표시됩니다.\n확인 후 해당 배치 작업이 즉시 실행됩니다.\n실행 중인 작업은 좌측에 초록색 점이 표시됩니다.',
  },
  {
    title: '이력 보기',
    content: '"이력 보기" 버튼을 클릭하면 해당 작업의 실행 이력 화면으로 이동합니다.\n과거 실행 결과, 소요 시간 등을 상세히 확인할 수 있습니다.',
  },
];

type StatusFilterKey = 'ALL' | 'STARTED' | 'COMPLETED' | 'FAILED' | 'NONE';
type SortKey = 'name' | 'recent' | 'status';
type ViewMode = 'card' | 'table';

interface StatusTabConfig {
  key: StatusFilterKey;
  label: string;
}

const STATUS_TABS: StatusTabConfig[] = [
  { key: 'ALL', label: '전체' },
  { key: 'STARTED', label: '실행 중' },
  { key: 'COMPLETED', label: '성공' },
  { key: 'FAILED', label: '실패' },
  { key: 'NONE', label: '미실행' },
];

const STATUS_ORDER: Record<string, number> = {
  FAILED: 0,
  STARTED: 1,
  COMPLETED: 2,
};

function getStatusOrder(job: JobDetailDto): number {
  if (!job.lastExecution) return 3;
  return STATUS_ORDER[job.lastExecution.status] ?? 4;
}

function matchesStatusFilter(job: JobDetailDto, filter: StatusFilterKey): boolean {
  if (filter === 'ALL') return true;
  if (filter === 'NONE') return job.lastExecution === null;
  return job.lastExecution?.status === filter;
}

export default function Jobs() {
  const navigate = useNavigate();
  const { showToast } = useToastContext();

  const [jobs, setJobs] = useState<JobDetailDto[]>([]);
  const [loading, setLoading] = useState(true);
  const [searchTerm, setSearchTerm] = useState('');
  const [statusFilter, setStatusFilter] = useState<StatusFilterKey>('ALL');
  const [sortKey, setSortKey] = useState<SortKey>('recent');
  const [viewMode, setViewMode] = useState<ViewMode>('table');

  const [guideOpen, setGuideOpen] = useState(false);

  // Execute modal (individual card)
  const [executeModalOpen, setExecuteModalOpen] = useState(false);
  const [targetJob, setTargetJob] = useState('');
  const [executing, setExecuting] = useState(false);


  const loadJobs = useCallback(async () => {
    try {
      const data = await batchApi.getJobsDetail();
      setJobs(data);
    } catch (err) {
      console.error('Jobs load failed:', err);
    } finally {
      setLoading(false);
    }
  }, []);

  usePoller(loadJobs, POLLING_INTERVAL);

  /** displayName 우선, 없으면 jobName */
  const getJobLabel = useCallback((job: JobDetailDto) => job.displayName || job.jobName, []);

  const statusCounts = useMemo(() => {
    const searchFiltered = searchTerm.trim()
      ? jobs.filter((job) => {
          const term = searchTerm.toLowerCase();
          return job.jobName.toLowerCase().includes(term)
            || (job.displayName?.toLowerCase().includes(term) ?? false);
        })
      : jobs;

    return STATUS_TABS.reduce<Record<StatusFilterKey, number>>(
      (acc, tab) => {
        acc[tab.key] = searchFiltered.filter((job) => matchesStatusFilter(job, tab.key)).length;
        return acc;
      },
      { ALL: 0, STARTED: 0, COMPLETED: 0, FAILED: 0, NONE: 0 },
    );
  }, [jobs, searchTerm]);

  const filteredJobs = useMemo(() => {
    let result = jobs;

    if (searchTerm.trim()) {
      const term = searchTerm.toLowerCase();
      result = result.filter((job) =>
        job.jobName.toLowerCase().includes(term)
        || (job.displayName?.toLowerCase().includes(term) ?? false),
      );
    }

    result = result.filter((job) => matchesStatusFilter(job, statusFilter));

    result = [...result].sort((a, b) => {
      if (sortKey === 'name') {
        return getJobLabel(a).localeCompare(getJobLabel(b));
      }
      if (sortKey === 'recent') {
        const aTime = a.lastExecution?.startTime ? new Date(a.lastExecution.startTime).getTime() : 0;
        const bTime = b.lastExecution?.startTime ? new Date(b.lastExecution.startTime).getTime() : 0;
        return bTime - aTime;
      }
      if (sortKey === 'status') {
        return getStatusOrder(a) - getStatusOrder(b);
      }
      return 0;
    });

    return result;
  }, [jobs, searchTerm, statusFilter, sortKey]);

  const handleExecuteClick = (jobName: string) => {
    setTargetJob(jobName);
    setExecuteModalOpen(true);
  };

  const handleConfirmExecute = async () => {
    if (!targetJob) return;
    setExecuting(true);
    try {
      const result = await batchApi.executeJob(targetJob);
      showToast(
        result.message || `${targetJob} 실행 요청 완료`,
        'success',
      );
      setExecuteModalOpen(false);
    } catch (err) {
      showToast(
        `실행 실패: ${err instanceof Error ? err.message : '알 수 없는 오류'}`,
        'error',
      );
    } finally {
      setExecuting(false);
    }
  };

  const handleViewHistory = (jobName: string) => {
    navigate(`/executions?job=${encodeURIComponent(jobName)}`);
  };

  if (loading) return <LoadingSpinner />;

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between flex-wrap gap-3">
        <div className="flex items-center gap-2">
          <h1 className="text-2xl font-bold text-wing-text">배치 작업 목록</h1>
          <HelpButton onClick={() => setGuideOpen(true)} />
        </div>
        <span className="text-sm text-wing-muted">
          총 {jobs.length}개 작업
        </span>
      </div>

      {/* Status Filter Tabs */}
      <div className="flex flex-wrap gap-2">
        {STATUS_TABS.map((tab) => (
          <button
            key={tab.key}
            onClick={() => setStatusFilter(tab.key)}
            className={`inline-flex items-center gap-1.5 px-4 py-1.5 rounded-full text-sm font-medium transition-colors ${
              statusFilter === tab.key
                ? 'bg-wing-accent text-white'
                : 'bg-wing-card text-wing-muted hover:text-wing-text'
            }`}
          >
            {tab.label}
            <span
              className={`inline-flex items-center justify-center min-w-[1.25rem] h-5 px-1 rounded-full text-xs font-semibold ${
                statusFilter === tab.key
                  ? 'bg-white/25 text-white'
                  : 'bg-wing-border text-wing-muted'
              }`}
            >
              {statusCounts[tab.key]}
            </span>
          </button>
        ))}
      </div>

      {/* Search + Sort + View Toggle */}
      <div className="bg-wing-surface rounded-xl shadow-md p-4">
        <div className="flex gap-3 items-center flex-wrap">
          {/* Search */}
          <div className="relative flex-1 min-w-[200px]">
            <span className="absolute inset-y-0 left-3 flex items-center text-wing-muted">
              <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
                />
              </svg>
            </span>
            <input
              type="text"
              placeholder="작업명 검색..."
              value={searchTerm}
              onChange={(e) => setSearchTerm(e.target.value)}
              className="w-full pl-10 pr-4 py-2 border border-wing-border rounded-lg text-sm
                focus:ring-2 focus:ring-wing-accent focus:border-wing-accent outline-none"
            />
            {searchTerm && (
              <button
                onClick={() => setSearchTerm('')}
                className="absolute inset-y-0 right-3 flex items-center text-wing-muted hover:text-wing-text"
              >
                <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                </svg>
              </button>
            )}
          </div>

          {/* Sort dropdown */}
          <select
            value={sortKey}
            onChange={(e) => setSortKey(e.target.value as SortKey)}
            className="px-3 py-2 border border-wing-border rounded-lg text-sm bg-wing-surface text-wing-text
              focus:ring-2 focus:ring-wing-accent focus:border-wing-accent outline-none"
          >
            <option value="name">작업명순</option>
            <option value="recent">최신 실행순</option>
            <option value="status">상태별(실패 우선)</option>
          </select>

          {/* View mode toggle */}
          <div className="flex rounded-lg border border-wing-border overflow-hidden">
            <button
              onClick={() => setViewMode('table')}
              title="테이블 보기"
              className={`px-3 py-2 transition-colors ${
                viewMode === 'table'
                  ? 'bg-wing-accent text-white'
                  : 'bg-wing-surface text-wing-muted hover:text-wing-text'
              }`}
            >
              <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
              </svg>
            </button>
            <button
              onClick={() => setViewMode('card')}
              title="카드 보기"
              className={`px-3 py-2 transition-colors border-l border-wing-border ${
                viewMode === 'card'
                  ? 'bg-wing-accent text-white'
                  : 'bg-wing-surface text-wing-muted hover:text-wing-text'
              }`}
            >
              <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"
                />
              </svg>
            </button>
          </div>
        </div>

        {searchTerm && (
          <p className="mt-2 text-xs text-wing-muted">
            {filteredJobs.length}개 작업 검색됨
          </p>
        )}
      </div>

      {/* Job List */}
      {filteredJobs.length === 0 ? (
        <div className="bg-wing-surface rounded-xl shadow-md p-6">
          <EmptyState
            icon="🔍"
            message={searchTerm || statusFilter !== 'ALL' ? '검색 결과가 없습니다.' : '등록된 작업이 없습니다.'}
            sub={searchTerm || statusFilter !== 'ALL' ? '다른 검색어나 필터를 사용해 보세요.' : undefined}
          />
        </div>
      ) : viewMode === 'card' ? (
        /* Card View */
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
          {filteredJobs.map((job) => {
            const isRunning = job.lastExecution?.status === 'STARTED';
            const duration = job.lastExecution
              ? calculateDuration(job.lastExecution.startTime, job.lastExecution.endTime)
              : null;
            const showDuration =
              job.lastExecution?.endTime != null && duration !== null && duration !== '-';

            return (
              <div
                key={job.jobName}
                className={`bg-wing-surface rounded-xl shadow-md p-6
                  hover:shadow-lg hover:-translate-y-0.5 transition-all
                  ${isRunning ? 'border-l-4 border-emerald-500' : ''}`}
              >
                <div className="flex items-start justify-between mb-3">
                  <div>
                    <h3 className="text-sm font-semibold text-wing-text break-all leading-tight">
                      {getJobLabel(job)}
                    </h3>
                  </div>
                  <div className="flex items-center gap-2 ml-2 shrink-0">
                    {isRunning && (
                      <span className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse" />
                    )}
                    {job.lastExecution && (
                      <StatusBadge status={job.lastExecution.status} />
                    )}
                  </div>
                </div>

                {/* Job detail info */}
                <div className="mb-4 space-y-1">
                  {job.lastExecution ? (
                    <>
                      <p className="text-xs text-wing-muted">
                        마지막 실행: {formatDateTime(job.lastExecution.startTime)}
                      </p>
                      {showDuration && (
                        <p className="text-xs text-wing-muted">
                          소요 시간: {duration}
                        </p>
                      )}
                      {isRunning && !showDuration && (
                        <p className="text-xs text-emerald-500">
                          소요 시간: 실행 중...
                        </p>
                      )}
                    </>
                  ) : (
                    <p className="text-wing-muted text-xs">실행 이력 없음</p>
                  )}

                  <div className="flex items-center gap-2 pt-0.5">
                    {job.scheduleCron ? (
                      <span className="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-emerald-100 text-emerald-700">
                        자동
                      </span>
                    ) : (
                      <span className="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-wing-card text-wing-muted">
                        수동
                      </span>
                    )}
                    {job.scheduleCron && (
                      <span className="font-mono text-xs bg-wing-card px-2 py-0.5 rounded text-wing-muted">
                        {job.scheduleCron}
                      </span>
                    )}
                  </div>
                </div>

                <div className="flex gap-2">
                  <button
                    onClick={() => handleExecuteClick(job.jobName)}
                    className="flex-1 px-3 py-2 text-xs font-medium text-white bg-wing-accent rounded-lg
                      hover:bg-wing-accent/80 transition-colors"
                  >
                    실행
                  </button>
                  <button
                    onClick={() => handleViewHistory(job.jobName)}
                    className="flex-1 px-3 py-2 text-xs font-medium text-wing-accent bg-wing-accent/10 rounded-lg
                      hover:bg-wing-accent/15 transition-colors"
                  >
                    이력 보기
                  </button>
                </div>
              </div>
            );
          })}
        </div>
      ) : (
        /* Table View */
        <div className="bg-wing-surface rounded-xl shadow-md overflow-hidden">
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b border-wing-border bg-wing-card">
                  <th className="text-left px-4 py-3 text-xs font-semibold text-wing-muted uppercase tracking-wider">
                    작업명
                  </th>
                  <th className="text-left px-4 py-3 text-xs font-semibold text-wing-muted uppercase tracking-wider">
                    상태
                  </th>
                  <th className="text-left px-4 py-3 text-xs font-semibold text-wing-muted uppercase tracking-wider">
                    마지막 실행
                  </th>
                  <th className="text-left px-4 py-3 text-xs font-semibold text-wing-muted uppercase tracking-wider">
                    소요시간
                  </th>
                  <th className="text-left px-4 py-3 text-xs font-semibold text-wing-muted uppercase tracking-wider">
                    스케줄
                  </th>
                  <th className="text-right px-4 py-3 text-xs font-semibold text-wing-muted uppercase tracking-wider">
                    액션
                  </th>
                </tr>
              </thead>
              <tbody className="divide-y divide-wing-border">
                {filteredJobs.map((job) => {
                  const isRunning = job.lastExecution?.status === 'STARTED';
                  const duration = job.lastExecution
                    ? calculateDuration(job.lastExecution.startTime, job.lastExecution.endTime)
                    : '-';

                  return (
                    <tr
                      key={job.jobName}
                      className={`hover:bg-wing-hover transition-colors ${
                        isRunning ? 'border-l-4 border-emerald-500' : ''
                      }`}
                    >
                      <td className="px-4 py-3 font-medium text-wing-text break-all">
                        <div className="flex items-center gap-2">
                          {isRunning && (
                            <span className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse shrink-0" />
                          )}
                          <span>{getJobLabel(job)}</span>
                        </div>
                      </td>
                      <td className="px-4 py-3">
                        {job.lastExecution ? (
                          <StatusBadge status={job.lastExecution.status} />
                        ) : (
                          <span className="text-xs text-wing-muted">미실행</span>
                        )}
                      </td>
                      <td className="px-4 py-3 text-wing-muted">
                        {job.lastExecution
                          ? formatDateTime(job.lastExecution.startTime)
                          : '-'}
                      </td>
                      <td className="px-4 py-3 text-wing-muted">
                        {job.lastExecution ? duration : '-'}
                      </td>
                      <td className="px-4 py-3">
                        {job.scheduleCron ? (
                          <span className="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-emerald-100 text-emerald-700">
                            자동
                          </span>
                        ) : (
                          <span className="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-wing-card text-wing-muted">
                            수동
                          </span>
                        )}
                      </td>
                      <td className="px-4 py-3">
                        <div className="flex justify-end gap-2">
                          <button
                            onClick={() => handleExecuteClick(job.jobName)}
                            className="px-3 py-1.5 text-xs font-medium text-white bg-wing-accent rounded-lg
                              hover:bg-wing-accent/80 transition-colors"
                          >
                            실행
                          </button>
                          <button
                            onClick={() => handleViewHistory(job.jobName)}
                            className="px-3 py-1.5 text-xs font-medium text-wing-accent bg-wing-accent/10 rounded-lg
                              hover:bg-wing-accent/15 transition-colors"
                          >
                            이력보기
                          </button>
                        </div>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>
      )}

      <GuideModal
        open={guideOpen}
        pageTitle="배치 작업 목록"
        sections={JOBS_GUIDE}
        onClose={() => setGuideOpen(false)}
      />

      {/* Execute Modal (custom with date params) */}
      {executeModalOpen && (
        <div
          className="fixed inset-0 z-50 flex items-center justify-center bg-wing-overlay"
          onClick={() => setExecuteModalOpen(false)}
        >
          <div
            className="bg-wing-surface rounded-xl shadow-2xl p-6 max-w-md w-full mx-4"
            onClick={(e) => e.stopPropagation()}
          >
            <h3 className="text-lg font-semibold text-wing-text mb-2">작업 실행 확인</h3>
            <p className="text-wing-muted text-sm mb-4">
              &quot;{jobs.find((j) => j.jobName === targetJob)?.displayName || targetJob}&quot; 작업을 실행하시겠습니까?
            </p>

            <div className="flex justify-end gap-3 mt-6">
              <button
                onClick={() => setExecuteModalOpen(false)}
                className="px-4 py-2 text-sm font-medium text-wing-text bg-wing-card rounded-lg
                  hover:bg-wing-hover transition-colors"
              >
                취소
              </button>
              <button
                onClick={handleConfirmExecute}
                disabled={executing}
                className="px-4 py-2 text-sm font-medium text-white bg-wing-accent rounded-lg
                  hover:bg-wing-accent/80 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
              >
                {executing ? '실행 중...' : '실행'}
              </button>
            </div>
          </div>
        </div>
      )}

    </div>
  );
}
