'use client';

import { useState, useEffect } from 'react';

interface DiffLine {
  value: string;
  added?: boolean;
  removed?: boolean;
}

type DiffMode = 'unified' | 'side-by-side';

interface VersionDiffProps {
  oldContent: string;
  newContent: string;
  oldTitle?: string;
  newTitle?: string;
}

export default function VersionDiff({ oldContent, newContent, oldTitle, newTitle }: VersionDiffProps) {
  const [mode, setMode] = useState<DiffMode>('unified');
  const [diffResult, setDiffResult] = useState<DiffLine[]>([]);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    let cancelled = false;

    const computeDiff = async () => {
      setIsLoading(true);
      try {
        const { diffLines } = await import('diff');
        const result = diffLines(oldContent, newContent);
        if (!cancelled) {
          setDiffResult(result);
        }
      } catch (e) {
        console.error('VersionDiff: diff calculation error', e);
      } finally {
        if (!cancelled) setIsLoading(false);
      }
    };

    computeDiff();
    return () => { cancelled = true; };
  }, [oldContent, newContent]);

  const hasChanges = diffResult.some(part => part.added || part.removed);

  if (isLoading) {
    return (
      <div className="flex items-center justify-center py-8">
        <div className="w-6 h-6 border-2 border-indigo-500 border-t-transparent rounded-full animate-spin" />
        <span className="ml-2 text-sm text-gray-500">diff 계산 중...</span>
      </div>
    );
  }

  if (!hasChanges) {
    return (
      <div className="text-center py-8 text-gray-400 text-sm font-medium">
        변경 사항이 없습니다
      </div>
    );
  }

  return (
    <div className="border border-gray-200 rounded-xl overflow-hidden">
      {/* 모드 토글 */}
      <div className="flex items-center justify-between px-4 py-2 bg-gray-50 border-b border-gray-200">
        <div className="text-xs font-bold text-gray-500">버전 비교</div>
        <div className="flex items-center bg-gray-200 rounded-lg p-0.5">
          <button
            onClick={() => setMode('unified')}
            className={`px-3 py-1 text-xs font-medium rounded-md transition-all ${
              mode === 'unified'
                ? 'bg-white text-gray-800 shadow-sm'
                : 'text-gray-500 hover:text-gray-700'
            }`}
          >
            Unified
          </button>
          <button
            onClick={() => setMode('side-by-side')}
            className={`px-3 py-1 text-xs font-medium rounded-md transition-all ${
              mode === 'side-by-side'
                ? 'bg-white text-gray-800 shadow-sm'
                : 'text-gray-500 hover:text-gray-700'
            }`}
          >
            Side-by-Side
          </button>
        </div>
      </div>

      {mode === 'unified' ? (
        <UnifiedView diffResult={diffResult} />
      ) : (
        <SideBySideView
          oldContent={oldContent}
          newContent={newContent}
          oldTitle={oldTitle}
          newTitle={newTitle}
          diffResult={diffResult}
        />
      )}
    </div>
  );
}

function UnifiedView({ diffResult }: { diffResult: DiffLine[] }) {
  let lineNum = 0;

  return (
    <div className="overflow-x-auto">
      <table className="w-full font-mono text-sm">
        <tbody>
          {diffResult.map((part, partIndex) => {
            const lines = part.value.split('\n');
            // 마지막 빈 문자열 제거 (trailing newline)
            if (lines[lines.length - 1] === '') lines.pop();

            return lines.map((line, lineIndex) => {
              if (!part.added) lineNum++;
              const key = `${partIndex}-${lineIndex}`;
              const currentLine = lineNum;

              if (part.added) {
                return (
                  <tr key={key} className="bg-green-50">
                    <td className="select-none text-right text-gray-400 px-3 py-0.5 text-xs w-10 border-r border-gray-200">
                      {currentLine}
                    </td>
                    <td className="px-3 py-0.5 text-green-800">
                      <span className="text-green-500 mr-2 font-bold">+</span>
                      {line}
                    </td>
                  </tr>
                );
              }

              if (part.removed) {
                return (
                  <tr key={key} className="bg-red-50">
                    <td className="select-none text-right text-gray-400 px-3 py-0.5 text-xs w-10 border-r border-gray-200">
                      {currentLine}
                    </td>
                    <td className="px-3 py-0.5 text-red-800">
                      <span className="text-red-500 mr-2 font-bold">-</span>
                      {line}
                    </td>
                  </tr>
                );
              }

              return (
                <tr key={key} className="hover:bg-gray-50/50">
                  <td className="select-none text-right text-gray-400 px-3 py-0.5 text-xs w-10 border-r border-gray-200">
                    {currentLine}
                  </td>
                  <td className="px-3 py-0.5 text-gray-700">
                    <span className="text-gray-300 mr-2"> </span>
                    {line}
                  </td>
                </tr>
              );
            });
          })}
        </tbody>
      </table>
    </div>
  );
}

function SideBySideView({
  oldContent,
  newContent,
  oldTitle,
  newTitle,
  diffResult,
}: {
  oldContent: string;
  newContent: string;
  oldTitle?: string;
  newTitle?: string;
  diffResult: DiffLine[];
}) {
  const oldLines = oldContent.split('\n');
  const newLines = newContent.split('\n');

  // 삭제된 라인 인덱스 집합
  const removedLineSet = new Set<number>();
  const addedLineSet = new Set<number>();

  let oldIdx = 0;
  let newIdx = 0;

  for (const part of diffResult) {
    const lines = part.value.split('\n');
    if (lines[lines.length - 1] === '') lines.pop();

    for (let i = 0; i < lines.length; i++) {
      if (part.removed) {
        removedLineSet.add(oldIdx++);
      } else if (part.added) {
        addedLineSet.add(newIdx++);
      } else {
        oldIdx++;
        newIdx++;
      }
    }
  }

  return (
    <div className="grid grid-cols-1 lg:grid-cols-2 divide-y lg:divide-y-0 lg:divide-x divide-gray-200">
      {/* 왼쪽: 이전 버전 */}
      <div className="overflow-x-auto">
        <div className="px-3 py-2 bg-red-50 border-b border-red-100">
          <span className="text-xs font-bold text-red-600">{oldTitle || '이전 버전'}</span>
        </div>
        <table className="w-full font-mono text-sm">
          <tbody>
            {oldLines.map((line, idx) => (
              <tr key={idx} className={removedLineSet.has(idx) ? 'bg-red-50' : 'hover:bg-gray-50/50'}>
                <td className="select-none text-right text-gray-400 px-2 py-0.5 text-xs w-8 border-r border-gray-200">
                  {idx + 1}
                </td>
                <td className={`px-3 py-0.5 ${removedLineSet.has(idx) ? 'text-red-800' : 'text-gray-700'}`}>
                  {removedLineSet.has(idx) && (
                    <span className="text-red-400 mr-1 font-bold">-</span>
                  )}
                  {line}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      {/* 오른쪽: 새 버전 */}
      <div className="overflow-x-auto">
        <div className="px-3 py-2 bg-green-50 border-b border-green-100">
          <span className="text-xs font-bold text-green-600">{newTitle || '새 버전'}</span>
        </div>
        <table className="w-full font-mono text-sm">
          <tbody>
            {newLines.map((line, idx) => (
              <tr key={idx} className={addedLineSet.has(idx) ? 'bg-green-50' : 'hover:bg-gray-50/50'}>
                <td className="select-none text-right text-gray-400 px-2 py-0.5 text-xs w-8 border-r border-gray-200">
                  {idx + 1}
                </td>
                <td className={`px-3 py-0.5 ${addedLineSet.has(idx) ? 'text-green-800' : 'text-gray-700'}`}>
                  {addedLineSet.has(idx) && (
                    <span className="text-green-400 mr-1 font-bold">+</span>
                  )}
                  {line}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}
