import { useState, useDeferredValue } from 'react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { LocalTask, LocalFileEntry, SubtaskActivity, Visibility, fetchMyOrgs, updateLocalTask } from '../../api';
import { relativeTime } from '../../lib/utils';
import { DetailTabId } from '../../lib/urlState';
import { DetailHeader } from './DetailHeader';
import { ContinueWithPieceDialog } from './ContinueWithPieceDialog';
import { SkeletonDetailPanel } from '../shared/Skeleton';
import { OverviewTab } from './tabs/OverviewTab';
import { ProgressTab } from './tabs/ProgressTab';
import { FilesTab } from './tabs/FilesTab';
import { TraceTab } from './tabs/TraceTab';
import { BrowserTab } from './tabs/BrowserTab';
import { ConsoleTab } from './tabs/ConsoleTab';
import { BrowserSessionPanel } from '../browser/BrowserSessionPanel';
import type { ConsoleStatus } from '../../lib/ssh-console-types';
import { useAuthState } from '../../App';
import type { SubtaskFilePreviewHandler } from './tabs/SubtasksPanel';

interface LocalDetailPanelProps {
  task: LocalTask | null;
  taskId: number;
  section: 'workspace' | 'input' | 'output' | 'logs';
  currentPath: string;
  entries: LocalFileEntry[];
  pathSegments: string[];
  loading: boolean;
  detailTab: DetailTabId;
  detailWidth: 'normal' | 'focused';
  showWidthToggle: boolean;
  onTabChange: (tab: DetailTabId) => void;
  onWidthToggle: () => void;
  onClose: () => void;
  onDelete?: () => Promise<void>;
  onSectionChange: (section: 'workspace' | 'input' | 'output' | 'logs') => void;
  onNavigate: (path: string) => void;
  onPreview: (path: string, name: string) => void;
  onViewFullLog: () => void;
  onRefresh?: () => void;
  isRefreshing?: boolean;
  subtaskActivities?: SubtaskActivity[];
  onSubtaskFilePreview?: SubtaskFilePreviewHandler;
  shareToken?: string | null;
  onShareChange?: () => void;
}

const LOCAL_TABS: Array<{ id: DetailTabId; label: string }> = [
  { id: 'overview', label: '概要' },
  { id: 'activity', label: '進捗' },
  { id: 'files', label: 'ファイル' },
  { id: 'trace', label: 'トレース' },
  { id: 'browser', label: 'ブラウザ' },
  { id: 'ssh', label: 'SSH' },
];

export function LocalDetailPanel({
  task, taskId, section, currentPath, entries, pathSegments,
  loading, detailTab, detailWidth, showWidthToggle,
  onTabChange, onWidthToggle, onClose, onDelete, onSectionChange, onNavigate, onPreview, onViewFullLog,
  onRefresh, isRefreshing, subtaskActivities, onSubtaskFilePreview,
  shareToken, onShareChange,
}: LocalDetailPanelProps) {
  // Deferred tab id for content rendering. The tab indicator (DetailHeader)
  // uses `detailTab` (immediate) so the underline jumps on click. The heavy
  // content area below uses `deferredDetailTab` so expensive panels
  // (ProgressTab / TraceTab) don't block the click → indicator paint.
  // When detailTab !== deferredDetailTab we know a transition is in flight.
  const deferredDetailTab = useDeferredValue(detailTab);
  const tabTransitionPending = detailTab !== deferredDetailTab;
  const [deleting, setDeleting] = useState(false);
  const [continueOpen, setContinueOpen] = useState(false);
  const [editingVisibility, setEditingVisibility] = useState(false);
  const [savingVisibility, setSavingVisibility] = useState(false);
  const [editVisibility, setEditVisibility] = useState<Visibility>('private');
  const [editScopeOrgId, setEditScopeOrgId] = useState<string | null>(null);
  const [editError, setEditError] = useState<string | null>(null);
  const qc = useQueryClient();
  const authState = useAuthState();
  const currentUserId = authState.mode === 'authenticated' ? authState.user.id : null;
  const currentUserRole = authState.mode === 'authenticated' ? authState.user.role : null;
  const canEditVisibility = task
    ? (currentUserRole === 'admin' || (currentUserId !== null && task.ownerId === currentUserId))
    : false;
  const { data: orgs = [] } = useQuery({
    queryKey: ['my-orgs'],
    queryFn: fetchMyOrgs,
    staleTime: 5 * 60 * 1000,
    enabled: editingVisibility,
  });

  // SSH console tab visibility: show whenever an active console session exists for this task.
  // (Piece-level pre-show via latestJob.allowedTools is not currently exposed by the API; this
  // fallback covers the real case where the AI has actually opened a session.)
  const { data: consoleStatus } = useQuery<ConsoleStatus>({
    queryKey: ['console-status', task?.id],
    queryFn: async () => {
      const r = await fetch(`/api/local/tasks/${task!.id}/console/status`);
      return r.ok ? r.json() : { active: false };
    },
    enabled: !!task,
    refetchInterval: 5000,
  });
  const showSshTab = consoleStatus?.active === true;
  const visibleTabs = LOCAL_TABS.filter((t) => t.id !== 'ssh' || showSshTab);

  const handleStartEdit = () => {
    if (!task) return;
    setEditVisibility((task.visibility as Visibility) ?? 'private');
    setEditScopeOrgId(task.visibilityScopeOrgId ?? null);
    setEditError(null);
    setEditingVisibility(true);
  };

  const handleSaveVisibility = async () => {
    if (!task) return;
    setEditError(null);
    setSavingVisibility(true);
    try {
      await updateLocalTask(task.id, {
        visibility: editVisibility,
        visibilityScopeOrgId: editVisibility === 'org' ? editScopeOrgId : null,
      });
      await qc.invalidateQueries({ queryKey: ['localTaskDetail', task.id] });
      setEditingVisibility(false);
    } catch (err) {
      setEditError(err instanceof Error ? err.message : String(err));
    } finally {
      setSavingVisibility(false);
    }
  };

  const handleDelete = async () => {
    if (!onDelete) return;
    if (!window.confirm('このタスクを削除しますか？この操作は取り消せません。')) return;
    setDeleting(true);
    try {
      await onDelete();
    } finally {
      setDeleting(false);
    }
  };

  const jobStatus = task?.latestJob?.status;
  const isActiveJob = jobStatus === 'running' || jobStatus === 'dispatching';

  return (
    <div className="flex flex-col h-full overflow-hidden bg-surface">
      <DetailHeader
        title={`Task #${taskId}`}
        subtitle="ローカルワークスペース"
        tabs={visibleTabs}
        activeTab={detailTab}
        tabTransitionPending={tabTransitionPending}
        onTabChange={onTabChange}
        onClose={onClose}
        detailWidth={detailWidth}
        onWidthToggle={showWidthToggle ? onWidthToggle : undefined}
        taskId={taskId}
        shareToken={shareToken}
        onShareChange={onShareChange}
        latestJobStatus={task?.latestJob?.status ?? null}
        onContinue={task?.latestJob ? () => setContinueOpen(true) : undefined}
      />
      {continueOpen && task?.latestJob && (
        <ContinueWithPieceDialog
          taskId={taskId}
          prevJob={{
            id: task.latestJob.id,
            // task.pieceName tracks last-piece-wins after each Continue, so
            // it equals the latest job's piece.
            pieceName: task.pieceName,
            status: task.latestJob.status,
          }}
          onClose={() => setContinueOpen(false)}
        />
      )}
      <div className={`flex-1 min-h-0 p-3 ${detailTab === 'ssh' ? 'overflow-hidden flex flex-col' : 'overflow-y-auto'}`}>
        {loading && !task && <SkeletonDetailPanel />}
        {task && (
          <>
            <div className="mb-2 flex items-center gap-2 text-2xs text-slate-500 flex-wrap">
              <span>作成者: <b>{task.ownerName ?? 'system'}</b></span>
              <span>·</span>
              <span>{relativeTime(task.createdAt)}</span>
              {task.visibility === 'private' && <span>· 🔒 非公開</span>}
              {task.visibility === 'org' && <span>· 🏢 {task.visibilityScopeOrgName ?? 'org'}</span>}
              {task.visibility === 'public' && <span>· 🌐 公開</span>}
              {canEditVisibility && !editingVisibility && (
                <button
                  className="ml-2 underline text-slate-500 hover:text-slate-700"
                  onClick={handleStartEdit}
                >
                  変更
                </button>
              )}
            </div>
            {editingVisibility && (
              <div className="mb-3 p-2.5 border border-hairline rounded-md bg-white text-xs">
                <div className="flex gap-3 flex-wrap">
                  <label className="flex items-center gap-1">
                    <input
                      type="radio"
                      checked={editVisibility === 'private'}
                      onChange={() => setEditVisibility('private')}
                    />
                    🔒 非公開
                  </label>
                  <label className="flex items-center gap-1">
                    <input
                      type="radio"
                      checked={editVisibility === 'org'}
                      onChange={() => {
                        setEditVisibility('org');
                        if (!editScopeOrgId && orgs.length > 0) setEditScopeOrgId(orgs[0].orgId);
                      }}
                      disabled={orgs.length === 0}
                    />
                    🏢 組織
                  </label>
                  <label className="flex items-center gap-1">
                    <input
                      type="radio"
                      checked={editVisibility === 'public'}
                      onChange={() => setEditVisibility('public')}
                    />
                    🌐 公開
                  </label>
                </div>
                {editVisibility === 'org' && orgs.length > 1 && (
                  <select
                    className="mt-2 px-2 h-7 border border-hairline rounded-md text-xs bg-white focus:outline-none focus:ring-2 focus:ring-accent-ring"
                    value={editScopeOrgId ?? ''}
                    onChange={e => setEditScopeOrgId(e.target.value)}
                  >
                    {orgs.map(o => <option key={o.orgId} value={o.orgId}>{o.orgName}</option>)}
                  </select>
                )}
                {editVisibility === 'org' && orgs.length === 1 && (
                  <div className="mt-1 text-2xs text-slate-500">共有先: {orgs[0].orgName}</div>
                )}
                {editVisibility === 'org' && orgs.length === 0 && (
                  <div className="mt-1 text-2xs text-slate-400">組織を使うには Gitea でログインしてください</div>
                )}
                {editError && <div className="mt-1 text-2xs text-red-600">{editError}</div>}
                <div className="mt-2 flex gap-2">
                  <button
                    disabled={savingVisibility}
                    onClick={() => void handleSaveVisibility()}
                    className="px-3 h-7 bg-accent text-accent-fg rounded-md text-xs font-semibold disabled:opacity-50 hover:bg-accent-deep transition-colors"
                  >
                    {savingVisibility ? '保存中...' : '保存'}
                  </button>
                  <button
                    disabled={savingVisibility}
                    onClick={() => { setEditingVisibility(false); setEditError(null); }}
                    className="px-3 h-7 border border-hairline rounded-md text-xs text-slate-600 hover:bg-surface transition-colors"
                  >
                    キャンセル
                  </button>
                </div>
              </div>
            )}
            {task?.latestJob?.status === 'waiting_human' && task?.latestJob?.waitReason === 'browser_login' && (
              <BrowserSessionPanel />
            )}
            {deferredDetailTab === 'overview' && <OverviewTab task={task} subtaskActivities={subtaskActivities} onSubtaskFilePreview={onSubtaskFilePreview} />}
            {deferredDetailTab === 'activity' && <ProgressTab task={task} onViewFullLog={onViewFullLog} subtaskActivities={subtaskActivities} />}
            {deferredDetailTab === 'files' && <FilesTab section={section} currentPath={currentPath} entries={entries} pathSegments={pathSegments} taskId={taskId} onSectionChange={onSectionChange} onNavigate={onNavigate} onPreview={onPreview} onRefresh={onRefresh} isRefreshing={isRefreshing} />}
            {deferredDetailTab === 'trace' && <TraceTab taskId={taskId} />}
            {deferredDetailTab === 'browser' && <BrowserTab taskId={taskId} />}
            {deferredDetailTab === 'ssh' && <ConsoleTab taskId={taskId} />}
          </>
        )}
      </div>
      {!loading && task && (
        <div className="flex-shrink-0 border-t border-hairline bg-white px-3 py-2.5">
          <div className="flex gap-2 items-center">
            {onDelete && !isActiveJob ? (
              <button
                disabled={deleting}
                onClick={handleDelete}
                className="px-3 h-7 bg-white border border-red-200 text-red-700 rounded-md text-xs font-medium disabled:opacity-50 hover:bg-red-50 transition-colors"
              >
                {deleting ? '削除中...' : '削除'}
              </button>
            ) : null}
          </div>
        </div>
      )}
    </div>
  );
}
