import { useCallback, useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { SpaceRail } from './SpaceRail';
import { SpaceDetail, type SpaceChatFilter } from './SpaceDetail';
import { WorkerStatusWidget } from '../dashboard/WorkerStatusWidget';
import { useIsMobile } from '../../hooks/useIsMobile';
import { useLocalStorageState } from '../../hooks/useLocalStorageState';
import type { CreateLocalTaskInput } from '../../api';

interface SpacesPageProps {
  spaceId?: string;
  spaceTaskId?: number;
  onSelectSpace: (id: string | undefined) => void;
  onSelectSpaceTask: (id: number) => void;
  onCreateTask: (input: CreateLocalTaskInput, attachments: Array<{ name: string; contentBase64: string }>) => Promise<void>;
  onOpenTask: (id: number) => void;
  chatFilter: SpaceChatFilter;
  onChatFilterChange: (next: Partial<SpaceChatFilter>) => void;
}

// レール幅の許容範囲。狭すぎると一覧が読めず、広すぎると詳細を圧迫するため上下限でクランプ。
const RAIL_MIN_PX = 180;
const RAIL_MAX_PX = 460;
const RAIL_DEFAULT_PX = 256;

function clampRailWidth(px: number): number {
  if (Number.isNaN(px)) return RAIL_DEFAULT_PX;
  return Math.max(RAIL_MIN_PX, Math.min(RAIL_MAX_PX, Math.round(px)));
}

export function SpacesPage({ spaceId, spaceTaskId, onSelectSpace, onSelectSpaceTask, onCreateTask, onOpenTask, chatFilter, onChatFilterChange }: SpacesPageProps) {
  const { t } = useTranslation('spaces');
  const isMobile = useIsMobile();
  const [railWidth, setRailWidth] = useLocalStorageState<number>('maestro.spaceRailWidth', RAIL_DEFAULT_PX);
  const [collapsed, setCollapsed] = useLocalStorageState<boolean>('maestro.spaceRailCollapsed', false);

  // 広幅でのみ可変幅・折りたたみを適用。狭幅は従来どおり全幅一覧 + spaceId で hidden 切替。
  const width = clampRailWidth(railWidth);
  const desktopCollapsed = !isMobile && collapsed;

  // レール本体の表示クラス。狭幅は w-full、広幅は inline style で幅を当てるため幅クラスを付けない。
  const railVisibilityClass = spaceId ? 'hidden md:flex' : 'flex';

  return (
    <div className="flex h-full min-h-0 overflow-hidden">
      {/* レール: 狭幅では全幅一覧。スペースを開いている狭幅では隠す（詳細が一覧を置き換える）。
          広幅はユーザー可変幅（ドラッグ）＋折りたたみ可能。
          縦は flex-col で、スペース一覧が残り高さを占め、ワーカー/GPU 状況が下部フッターに常駐する。 */}
      {desktopCollapsed ? (
        // 折りたたみ時: 細い再オープン用ストリップだけを残す。詳細が空いた幅を受け取る。
        <button
          type="button"
          data-testid="space-rail-collapse"
          onClick={() => setCollapsed(false)}
          aria-expanded={false}
          title={t('page.expandRail')}
          className="hidden md:flex w-7 shrink-0 flex-col items-center justify-center gap-2 border-r border-hairline bg-surface text-slate-400 transition-colors hover:bg-slate-100 hover:text-slate-600"
        >
          <svg className="h-4 w-4" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <path d="M6 4l4 4-4 4" />
          </svg>
          <span className="text-[10px] font-bold uppercase tracking-wider [writing-mode:vertical-rl]">{t('page.railLabel')}</span>
        </button>
      ) : (
        <div
          className={`w-full md:w-auto md:shrink-0 relative flex flex-col min-h-0 border-r border-hairline bg-surface ${railVisibilityClass}`}
          style={isMobile ? undefined : { width }}
        >
          {/* 広幅のみ: 折りたたみボタン（ヘッダー右上の薄いツールバー）。 */}
          <div className="hidden md:flex shrink-0 items-center justify-end border-b border-hairline px-2 py-1">
            <button
              type="button"
              data-testid="space-rail-collapse"
              onClick={() => setCollapsed(true)}
              aria-expanded
              title={t('page.collapseRail')}
              className="rounded p-1 text-slate-400 transition-colors hover:bg-slate-100 hover:text-slate-600"
            >
              <svg className="h-4 w-4" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                <path d="M10 4l-4 4 4 4" />
              </svg>
            </button>
          </div>
          <div className="min-h-0 flex-1 overflow-hidden">
            <SpaceRail selectedId={spaceId} onSelect={onSelectSpace} />
          </div>
          <WorkerStatusFooter />
          {/* 広幅のみ: 右端のドラッグハンドルで幅を調整。狭幅では非表示。 */}
          {!isMobile && (
            <RailResizeHandle
              width={width}
              onResize={px => setRailWidth(clampRailWidth(px))}
            />
          )}
        </div>
      )}
      {/* 詳細: 狭幅ではスペース選択時のみ全幅表示。未選択の狭幅では隠す。広幅は常時表示。 */}
      <div className={`min-w-0 flex-1 flex-col ${spaceId ? 'flex' : 'hidden md:flex'}`}>
        {/* 狭幅専用: スペース一覧へ戻る。広幅ではレールが常時見えるので不要。
            狭幅でチャットを開いているときは隠す（チャット側の「一覧へ」が直近の戻る導線で、
            スペース一覧へはチャット一覧から辿れるため、戻るボタンの重複を避ける）。 */}
        {spaceId && (
          <button
            type="button"
            data-testid="space-back-to-list"
            onClick={() => onSelectSpace(undefined)}
            className={`${spaceTaskId != null ? 'hidden' : 'md:hidden flex'} w-full items-center gap-1 border-b border-hairline bg-surface px-3 py-2 text-xs font-semibold text-slate-600 hover:text-slate-900`}
          >
            <svg className="h-3.5 w-3.5" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M10 4l-4 4 4 4" />
            </svg>
            {t('page.railList')}
          </button>
        )}
        <div className="min-h-0 flex-1">
          <SpaceDetail
            spaceId={spaceId}
            spaceTaskId={spaceTaskId}
            onSelectSpace={onSelectSpace}
            onSelectSpaceTask={onSelectSpaceTask}
            onCreateTask={onCreateTask}
            onOpenTask={onOpenTask}
            chatFilter={chatFilter}
            onChatFilterChange={onChatFilterChange}
          />
        </div>
      </div>
    </div>
  );
}

// レール右端のドラッグハンドル。mousedown→mousemove→mouseup でレール幅を更新する。
// 親が clamp するので、ここでは絶対 X 座標からレール左端基準の幅を計算するだけ。
// latest-ref パターンで drag 中に listener を貼り直さない。
function RailResizeHandle({ width, onResize }: { width: number; onResize: (px: number) => void }) {
  const { t } = useTranslation('spaces');
  const onResizeRef = useRef(onResize);
  onResizeRef.current = onResize;
  const draggingRef = useRef(false);
  const handleRef = useRef<HTMLDivElement>(null);
  const railLeftRef = useRef(0);
  const [active, setActive] = useState(false);

  useEffect(() => {
    const handleMove = (e: PointerEvent) => {
      if (!draggingRef.current) return;
      onResizeRef.current(e.clientX - railLeftRef.current);
    };
    const handleUp = () => {
      if (!draggingRef.current) return;
      draggingRef.current = false;
      document.body.style.cursor = '';
      document.body.style.userSelect = '';
      setActive(false);
    };
    window.addEventListener('pointermove', handleMove);
    window.addEventListener('pointerup', handleUp);
    window.addEventListener('pointercancel', handleUp);
    return () => {
      window.removeEventListener('pointermove', handleMove);
      window.removeEventListener('pointerup', handleUp);
      window.removeEventListener('pointercancel', handleUp);
    };
  }, []);

  const handlePointerDown = useCallback((e: React.PointerEvent<HTMLDivElement>) => {
    e.preventDefault();
    // レール左端の絶対 X を記録（ハンドル位置 - 現在幅）。
    const rect = handleRef.current?.getBoundingClientRect();
    railLeftRef.current = rect ? rect.right - width : e.clientX - width;
    draggingRef.current = true;
    document.body.style.cursor = 'col-resize';
    document.body.style.userSelect = 'none';
    setActive(true);
  }, [width]);

  return (
    <div
      ref={handleRef}
      role="separator"
      aria-orientation="vertical"
      aria-label={t('page.railResize')}
      data-testid="space-rail-resize"
      onPointerDown={handlePointerDown}
      className={`absolute top-0 right-0 z-10 h-full w-1.5 cursor-col-resize transition-colors hover:bg-slate-300/60 ${active ? 'bg-slate-400/60' : 'bg-transparent'}`}
      style={{ touchAction: 'none' }}
    >
      <div className="ml-auto h-full w-px bg-hairline" />
    </div>
  );
}

// レール下部に常駐する折りたたみ式のワーカー/GPU 状況パネル。Tasks ページと同じ
// WorkerStatusWidget を使い、空きスロット（=投入余地）を一目で確認できるようにする。
// 既定は折りたたみで、レール本体の高さを圧迫しない。開閉状態は localStorage に保存し、
// リロード・再マウントをまたいで維持する（毎回閉じ直す手間をなくす）。
function WorkerStatusFooter() {
  const { t } = useTranslation('spaces');
  const [open, setOpen] = useLocalStorageState('space.workerStatus.open', false);
  return (
    <div data-testid="space-worker-status" className="shrink-0 border-t border-hairline bg-surface">
      <button
        type="button"
        data-testid="space-worker-status-toggle"
        onClick={() => setOpen(v => !v)}
        aria-expanded={open}
        className="flex w-full items-center justify-between px-3 py-2 text-[11px] font-bold uppercase tracking-wider text-slate-500 transition-colors hover:text-slate-700"
      >
        <span>{t('page.workerGpu')}</span>
        <svg
          className={`h-3.5 w-3.5 transition-transform ${open ? 'rotate-180' : ''}`}
          viewBox="0 0 16 16"
          fill="none"
          stroke="currentColor"
          strokeWidth="2"
          strokeLinecap="round"
          strokeLinejoin="round"
        >
          <path d="M4 6l4 4 4-4" />
        </svg>
      </button>
      {open && (
        <div data-testid="space-worker-status-panel" className="max-h-48 overflow-auto px-2 pb-2">
          <WorkerStatusWidget />
        </div>
      )}
    </div>
  );
}
