import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { POLLING } from '../../../lib/constants.js';
import { usePictureInPicture } from '../../../lib/usePictureInPicture.js';
import { PipButton } from '../../browser/PipButton.js';
import { SaveRecordingButton } from '../../browser/SaveRecordingButton.js';

interface TaskSessionInfo {
  available: boolean;
  reason?: 'novnc_not_installed';
  sessionId?: string;
  novncPath?: string;
  display?: string;
  state?: 'ready' | 'user_interactive' | 'agent_controlled';
  lockedByJobId?: string | null;
  createdAt?: string;
  lastActiveAt?: string;
}

function useTaskSession(taskId: number) {
  return useQuery<TaskSessionInfo>({
    queryKey: ['task-session', taskId],
    queryFn: async () => {
      const r = await fetch(`/api/local/browser/sessions/task-session/${taskId}`);
      if (!r.ok) throw new Error(`HTTP ${r.status}`);
      return r.json() as Promise<TaskSessionInfo>;
    },
    refetchInterval: POLLING.FAST,
    refetchOnWindowFocus: true,
  });
}

function useReleaseSession(taskId: number) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: async () => {
      const r = await fetch(`/api/local/browser/sessions/task-session/${taskId}/release`, {
        method: 'POST',
      });
      if (!r.ok) throw new Error(`HTTP ${r.status}`);
      return r.json();
    },
    onSettled: () => {
      qc.invalidateQueries({ queryKey: ['task-session', taskId] });
    },
  });
}

/**
 * Task 詳細の "Browser" タブ。BrowseWeb / InteractiveBrowse がそのタスクで
 * noVNC session を起動していれば iframe で埋め込み、ユーザーが直接ブラウザを
 * 操作できる。可視性チェックは API 層 (GET /task-session/:taskId) が行うので
 * ここではタブ自体を全員に見せて構わない (見えないユーザーには available:false が返る)。
 */
export function BrowserTab({ taskId }: { taskId: number }) {
  const { data, isLoading, isError, error } = useTaskSession(taskId);
  const release = useReleaseSession(taskId);
  const pip = usePictureInPicture(data?.novncPath ?? null, `noVNC — Task #${taskId}`);

  if (isLoading) {
    return (
      <div className="flex items-center justify-center py-12 text-sm text-slate-500">
        読み込み中…
      </div>
    );
  }

  if (isError) {
    const msg = error instanceof Error ? error.message : String(error);
    return (
      <div className="p-4 text-sm text-red-700">
        ブラウザセッション情報の取得に失敗しました: {msg}
      </div>
    );
  }

  if (!data?.available) {
    if (data?.reason === 'novnc_not_installed') {
      return (
        <div className="bg-white border border-amber-300 rounded-md p-6 text-sm text-slate-700">
          <p className="font-medium text-amber-800 mb-2">noVNC の Web 配布物 (vnc.html) が配置されていません</p>
          <p className="text-xs leading-relaxed mb-2">
            このタスクのブラウザセッションは存在しますが、noVNC の HTML/JS 一式が
            <code className="mx-1 px-1 rounded bg-slate-100 font-mono text-2xs">vendor/noVNC/</code>
            に無いため iframe を表示できません。
          </p>
          <p className="text-xs leading-relaxed mb-2">
            以下のいずれかの方法でセットアップしてください:
          </p>
          <ul className="list-disc list-inside text-xs leading-relaxed space-y-1">
            <li>bare metal / dev 環境: <code className="px-1 rounded bg-slate-100 font-mono text-2xs">scripts/setup-novnc.sh</code> を実行</li>
            <li>Docker: 最新の Dockerfile (noVNC tarball を builder で展開) で再ビルド</li>
          </ul>
        </div>
      );
    }
    return (
      <div className="bg-white border border-hairline rounded-md p-6 text-center text-sm text-slate-600">
        <p className="font-medium text-slate-800 mb-1">このタスクのブラウザセッションは現在アクティブではありません</p>
        <p className="text-xs leading-relaxed">
          BrowseWeb / InteractiveBrowse を含むジョブが実行中のときに、このタブから
          noVNC でブラウザを操作できます (5 秒ポーリング中)。
        </p>
      </div>
    );
  }

  return (
    <div className="bg-white border border-hairline rounded-md overflow-hidden flex flex-col" style={{ minHeight: '480px' }}>
      <div className="flex items-center justify-between border-b border-hairline px-3 py-2 text-2xs text-slate-500 gap-2">
        <span className="truncate">
          state: <span className="font-mono text-slate-700">{data.state ?? '-'}</span>
          {data.lockedByJobId && <> · job: <span className="font-mono">{data.lockedByJobId}</span></>}
        </span>
        <div className="flex items-center gap-2">
          <PipButton pip={pip} />
          <SaveRecordingButton taskId={taskId} />
          <a
            href={data.novncPath}
            target="_blank"
            rel="noopener noreferrer"
            className="text-2xs text-accent hover:underline"
          >
            新しいタブで開く ↗
          </a>
          <button
            type="button"
            onClick={() => {
              if (window.confirm('このタスクのブラウザセッションを終了します。よろしいですか?')) {
                release.mutate();
              }
            }}
            disabled={release.isPending}
            className="px-2 py-1 rounded-md text-2xs border border-hairline bg-white hover:bg-surface text-slate-700 disabled:opacity-50"
            title="セッションを destroy する。次回 BrowseWeb 実行時に再生成される"
          >
            {release.isPending ? '終了中…' : 'セッション終了'}
          </button>
        </div>
      </div>
      {pip.isOpen ? (
        <div
          className="flex-1 w-full flex items-center justify-center bg-slate-50 text-xs text-slate-500"
          style={{ minHeight: '480px' }}
        >
          PiP ウィンドウで表示中。閉じるとここに戻ります。
        </div>
      ) : (
        <iframe
          src={data.novncPath}
          title={`Task #${taskId} browser session`}
          className="flex-1 w-full border-0"
          style={{ minHeight: '480px' }}
          allow="clipboard-read; clipboard-write"
        />
      )}
    </div>
  );
}
