import { useEffect, useState } from 'react';
import { HelpText } from './HelpText';
import { FieldLabel, FieldInput } from './formUtils';
import { StringArrayEditor } from './StringArrayEditor';
import { NamespaceEditor } from './NamespaceEditor';
import type { SectionFormProps } from './types';

const TOOL_TABS = [
  { id: 'web', label: 'Web' },
  { id: 'vision', label: 'Vision / OCR' },
  { id: 'x', label: 'X / Twitter' },
  { id: 'maps', label: 'Maps' },
  { id: 'amazon', label: 'Amazon' },
  { id: 'speech', label: 'Speech' },
  { id: 'knowledge', label: 'Knowledge (DKS) [LEGACY]' },
  { id: 'office', label: 'Office' },
  { id: 'uploads', label: 'Uploads' },
  { id: 'user-folder', label: 'User Folder' },
] as const;

export type ToolTabId = (typeof TOOL_TABS)[number]['id'];

interface ToolsFormProps extends SectionFormProps {
  /**
   * Restrict the visible set of sub-tabs. When omitted, all tabs are shown.
   * Used by the Settings sidebar Step 3 restructure to route sub-section ids
   * (tools-web / tools-browser / tools-media / tools-external /
   * tools-legacy-knowledge) into the same ToolsForm with a narrowed scope.
   */
  visibleTabs?: readonly ToolTabId[];
}

export function ToolsForm({ config, onChange, visibleTabs }: ToolsFormProps) {
  const tools = config.tools ?? {};
  const tabsToShow = visibleTabs && visibleTabs.length > 0
    ? TOOL_TABS.filter(t => visibleTabs.includes(t.id))
    : TOOL_TABS;
  const [tab, setTab] = useState<ToolTabId>(tabsToShow[0]?.id ?? 'web');

  // When visibleTabs changes (sidebar section change), reset to first tab
  // of the new scope so we don't render a hidden tab's content.
  useEffect(() => {
    if (!tabsToShow.some(t => t.id === tab)) {
      setTab(tabsToShow[0]?.id ?? 'web');
    }
  }, [tabsToShow, tab]);

  return (
    <div className="space-y-5">
      <h2 className="text-base font-semibold text-slate-800">Tools</h2>

      <nav className="flex flex-wrap gap-1 border-b border-hairline -mt-2" aria-label="ツールカテゴリ">
        {tabsToShow.map(t => (
          <button
            key={t.id}
            type="button"
            onClick={() => setTab(t.id)}
            aria-current={tab === t.id ? 'page' : undefined}
            className={`px-3 py-1.5 text-xs border-b-2 -mb-px transition-colors ${
              tab === t.id
                ? 'border-accent font-semibold text-accent'
                : 'border-transparent text-slate-500 hover:text-slate-800'
            }`}
          >
            {t.label}
          </button>
        ))}
      </nav>

      {tab === 'web' && (
        <div className="space-y-5">
          <div>
            <FieldLabel>SearXNG URL</FieldLabel>
            <FieldInput value={tools.searxngUrl ?? ''} onChange={v => onChange('tools.searxngUrl', v)} />
            <HelpText>WebSearch のフォールバック用 SearXNG エンドポイント。</HelpText>
          </div>
          <div>
            <FieldLabel>WebFetch Timeout (秒)</FieldLabel>
            <FieldInput type="number" value={tools.webfetchTimeout ?? 30}
              onChange={v => onChange('tools.webfetchTimeout', Number(v))} />
          </div>
          <div>
            <FieldLabel>WebSearch Timeout (秒)</FieldLabel>
            <FieldInput type="number" value={tools.websearchTimeout ?? 15}
              onChange={v => onChange('tools.websearchTimeout', Number(v))} />
          </div>
          <div>
            <FieldLabel>SSRF Allowed Hosts</FieldLabel>
            <StringArrayEditor
              value={tools.webfetchAllowedHosts ?? []}
              onChange={v => onChange('tools.webfetchAllowedHosts', v)}
              placeholder="hostname or IP address" />
            <HelpText>SSRF 保護の例外ホスト名／IP アドレス。WebFetch・BrowseWeb のすべてに適用。</HelpText>
          </div>
        </div>
      )}

      {tab === 'vision' && (
        <div className="space-y-5">
          <div>
            <FieldLabel>Vision Model</FieldLabel>
            <FieldInput value={tools.visionModel ?? ''} onChange={v => onChange('tools.visionModel', v)} />
            <HelpText>画像分析に使用するモデル名（例: qwen2-vl:8b-instruct）</HelpText>
          </div>
          <div>
            <FieldLabel>Vision Base URL</FieldLabel>
            <FieldInput value={tools.visionBaseUrl ?? ''} onChange={v => onChange('tools.visionBaseUrl', v)}
              placeholder="Provider の Base URL と同じ場合は空欄" />
            <HelpText>Vision モデル用の API エンドポイント。</HelpText>
          </div>
          <div>
            <FieldLabel>Vision Timeout (秒)</FieldLabel>
            <FieldInput type="number" value={tools.visionTimeout ?? 60}
              onChange={v => onChange('tools.visionTimeout', Number(v))} />
          </div>
          <div>
            <FieldLabel>Vision Max Tokens</FieldLabel>
            <FieldInput type="number" value={tools.visionMaxTokens ?? 1024}
              onChange={v => onChange('tools.visionMaxTokens', Number(v))} />
          </div>
          <div>
            <FieldLabel>OCR Model</FieldLabel>
            <FieldInput value={tools.ocrModel ?? ''} onChange={v => onChange('tools.ocrModel', v)}
              placeholder="glm-ocr" />
            <HelpText>GLM-OCR で使用するモデル名。</HelpText>
          </div>
        </div>
      )}

      {tab === 'x' && (
        <div className="space-y-5">
          <div>
            <FieldLabel>X Auth Token</FieldLabel>
            <FieldInput type="password" value={tools.xAuthToken ?? ''} onChange={v => onChange('tools.xAuthToken', v)} />
            <HelpText>X / Twitter の auth_token cookie</HelpText>
          </div>
          <div>
            <FieldLabel>X ct0</FieldLabel>
            <FieldInput type="password" value={tools.xCt0 ?? ''} onChange={v => onChange('tools.xCt0', v)} />
            <HelpText>X / Twitter の ct0 cookie</HelpText>
          </div>
          <div>
            <FieldLabel>X CLI Command</FieldLabel>
            <FieldInput value={Array.isArray(tools.xCliCommand) ? tools.xCliCommand.join(' ') : (tools.xCliCommand ?? '')}
              onChange={v => onChange('tools.xCliCommand', v)} />
            <HelpText>twitter-cli の実行コマンド。</HelpText>
          </div>
          <div>
            <FieldLabel>X Timeout (秒)</FieldLabel>
            <FieldInput type="number" value={tools.xTimeout ?? 90}
              onChange={v => onChange('tools.xTimeout', Number(v))} />
          </div>
          <div>
            <FieldLabel>X Proxy</FieldLabel>
            <FieldInput value={tools.xProxy ?? ''} onChange={v => onChange('tools.xProxy', v)}
              placeholder="http://proxy:port" />
          </div>
          <div>
            <FieldLabel>X Chrome Profile</FieldLabel>
            <FieldInput value={tools.xChromeProfile ?? ''} onChange={v => onChange('tools.xChromeProfile', v)}
              placeholder="/path/to/chrome/profile" />
            <HelpText>Cookie 抽出用の Chrome プロファイルディレクトリ。</HelpText>
          </div>
        </div>
      )}

      {tab === 'maps' && (
        <div className="space-y-5">
          <div>
            <FieldLabel>Google Maps API Key</FieldLabel>
            <FieldInput type="password" value={tools.googleMapsApiKey ?? ''} onChange={v => onChange('tools.googleMapsApiKey', v)} />
            <HelpText>Google Maps Places / Directions API キー。未設定時は Nominatim / OSRM（無料）を使用。</HelpText>
          </div>
        </div>
      )}

      {tab === 'amazon' && (
        <div className="space-y-5">
          <div>
            <FieldLabel>Amazon Affiliate Tag</FieldLabel>
            <FieldInput value={tools.amazonAffiliateTag ?? ''} onChange={v => onChange('tools.amazonAffiliateTag', v)}
              placeholder="your-tag-22" />
            <HelpText>SearchAmazon で使用するアソシエイトタグ。</HelpText>
          </div>
          <div>
            <FieldLabel>Keepa API Key</FieldLabel>
            <FieldInput type="password" value={tools.keepaApiKey ?? ''} onChange={v => onChange('tools.keepaApiKey', v)} />
            <HelpText>Keepa API キー（価格履歴データ取得用）。未設定でもグラフ画像リンクは提供されます。</HelpText>
          </div>
        </div>
      )}

      {tab === 'speech' && (
        <div className="space-y-5">
          <div>
            <FieldLabel>Speech Server URL</FieldLabel>
            <FieldInput value={tools.speechServerUrl ?? ''} onChange={v => onChange('tools.speechServerUrl', v)}
              placeholder="http://localhost:8000/v1" />
            <HelpText>音声認識サーバーの API エンドポイント（TranscribeAudio 用）</HelpText>
          </div>
          <div>
            <FieldLabel>Speech Timeout (秒)</FieldLabel>
            <FieldInput type="number" value={tools.speechTimeout ?? 300}
              onChange={v => onChange('tools.speechTimeout', Number(v))} />
            <HelpText>長い音声ファイルに対応するためのタイムアウト</HelpText>
          </div>
          <div>
            <FieldLabel>Speech Language</FieldLabel>
            <FieldInput value={tools.speechLanguage ?? 'ja'} onChange={v => onChange('tools.speechLanguage', v)}
              placeholder="ja" />
            <HelpText>文字起こしのデフォルト言語コード</HelpText>
          </div>
        </div>
      )}

      {tab === 'knowledge' && (
        <div className="space-y-5">
          <div className="flex items-center gap-2">
            <h3 className="text-sm font-semibold text-slate-800">Knowledge (DKS)</h3>
            <span
              className="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-semibold uppercase tracking-wide bg-amber-100 text-amber-800 border border-amber-300"
              title="この機能は legacy です。新規の知識検索統合は MCP server 経由を推奨"
            >
              LEGACY
            </span>
          </div>
          <div
            role="note"
            className="rounded border border-amber-300 bg-amber-50 px-3 py-2 text-xs text-amber-900"
          >
            DKS 機能は <strong>legacy</strong> 化されており、新規の知識検索統合は{' '}
            <strong>MCP server 経由</strong> を推奨します。既存の namespace 設定は引き続き動作しますが、
            新規 namespace の追加はできません。{' '}
            <a
              href="/help"
              className="underline text-amber-900 hover:text-amber-700"
              target="_blank"
              rel="noopener noreferrer"
            >
              MCP 連携ガイドを開く
            </a>
          </div>
          <div>
            <FieldLabel>Knowledge Service URL</FieldLabel>
            <FieldInput value={tools.knowledgeServiceUrl ?? ''} onChange={v => onChange('tools.knowledgeServiceUrl', v)}
              placeholder="http://dks-server:8100" />
            <HelpText>Document Knowledge Server (DKS) の API エンドポイント。未設定時は knowledge ツール無効。</HelpText>
          </div>
          <div>
            <FieldLabel>Knowledge Namespaces</FieldLabel>
            <NamespaceEditor
              value={tools.knowledgeNamespaces ?? {}}
              onChange={v => onChange('tools.knowledgeNamespaces', v)}
              addDisabled
              addDisabledReason="新規 namespace 追加は MCP 経由を推奨"
              addDisabledHref="/help"
            />
            <HelpText>DKS の名前空間と API キーの組み合わせ。既存項目の編集・削除は可能ですが、新規追加は無効化されています。</HelpText>
          </div>
        </div>
      )}

      {tab === 'user-folder' && (
        <div className="space-y-5">
          <div>
            <FieldLabel>RunUserScript を有効化</FieldLabel>
            <label className="inline-flex items-center gap-2 text-[13px] text-slate-700">
              <input
                type="checkbox"
                checked={tools.userScriptsEnabled === true}
                onChange={e => onChange('tools.userScriptsEnabled', e.target.checked)}
              />
              <span>有効 (LLM の RunUserScript + scheduled script task が動作)</span>
            </label>
            <HelpText>
              plain runtime は Node <code>--permission</code> で sandbox 化され child_process / worker / tmpdir 外の FS アクセスを deny。
              browser-macros は Playwright の要件 (child_process / native bindings / network) で sandbox 不可、フル Node.js capability。
              信頼できるユーザーのみに有効化。
            </HelpText>
          </div>
          <div>
            <FieldLabel>実行許可ユーザー allowlist (空欄 = 全員)</FieldLabel>
            <StringArrayEditor
              value={tools.userScriptsAllowUserids ?? []}
              onChange={v => onChange('tools.userScriptsAllowUserids', v)}
              placeholder="user id (例: 12345)"
            />
            <HelpText>
              未指定なら <code>user_scripts_enabled</code> のみで制御。設定すると指定 ID のみ RunUserScript / scheduled script task が許可される。
            </HelpText>
          </div>
          <div>
            <FieldLabel>Trash Retention (日)</FieldLabel>
            <FieldInput type="number" value={tools.trashRetentionDays ?? 30}
              onChange={v => onChange('tools.trashRetentionDays', Number(v))} />
            <HelpText>
              <code>data/users/&#123;userId&#125;/trash/</code> のファイルを自動削除するまでの日数。
              起動時 + 24h 毎に sweep。0 を指定すると sweep のたびに即削除。デフォルト 30 日。
            </HelpText>
          </div>
        </div>
      )}

      {tab === 'uploads' && (
        <div className="space-y-5">
          <HelpText>UI からのアップロード API のリクエスト body 上限 (MB)</HelpText>
          <div>
            <FieldLabel>タスク作成・コメント時の最大アップロードサイズ</FieldLabel>
            <FieldInput type="number" value={tools.taskUploadMaxSizeMb ?? 50}
              onChange={v => onChange('tools.taskUploadMaxSizeMb', Number(v))} />
            <HelpText>
              <code>POST /api/local/tasks</code> および <code>POST /api/local/tasks/:id/comments</code> の
              リクエスト body 上限 (添付ファイルを base64 でエンコードした JSON 全体)。
              添付ファイルの実サイズは概ね <code>値 × 0.75</code> が目安 (例: 50 MB body ≒ 37 MB raw)。
              範囲は 1〜1000 MB にクランプ。デフォルト 50 MB。サーバ再起動なしで反映。
            </HelpText>
          </div>
        </div>
      )}

      {tab === 'office' && (
        <div className="space-y-5">
          <HelpText>Office ファイルサイズ上限 (MB)</HelpText>
          <div>
            <FieldLabel>ReadExcel 最大サイズ</FieldLabel>
            <FieldInput type="number" value={tools.officeExcelMaxSizeMb ?? 10}
              onChange={v => onChange('tools.officeExcelMaxSizeMb', Number(v))} />
            <HelpText>ReadExcel が受け付ける .xlsx / .xls ファイルの最大サイズ（デフォルト: 10 MB）</HelpText>
          </div>
          <div>
            <FieldLabel>ReadDocx 最大サイズ</FieldLabel>
            <FieldInput type="number" value={tools.officeDocxMaxSizeMb ?? 10}
              onChange={v => onChange('tools.officeDocxMaxSizeMb', Number(v))} />
            <HelpText>ReadDocx が受け付ける .docx ファイルの最大サイズ（デフォルト: 10 MB）</HelpText>
          </div>
          <div>
            <FieldLabel>ReadPdf 最大サイズ</FieldLabel>
            <FieldInput type="number" value={tools.officePdfMaxSizeMb ?? 10}
              onChange={v => onChange('tools.officePdfMaxSizeMb', Number(v))} />
            <HelpText>ReadPdf が受け付ける .pdf ファイルの最大サイズ（デフォルト: 10 MB）</HelpText>
          </div>
          <div>
            <FieldLabel>ReadPPTX 最大サイズ</FieldLabel>
            <FieldInput type="number" value={tools.officePptxMaxSizeMb ?? 50}
              onChange={v => onChange('tools.officePptxMaxSizeMb', Number(v))} />
            <HelpText>ReadPPTX が受け付ける .pptx ファイルの最大サイズ（デフォルト: 50 MB）</HelpText>
          </div>
          <div>
            <FieldLabel>ReadPPTX 展開後サイズ上限</FieldLabel>
            <FieldInput type="number" value={tools.officePptxMaxUncompressedMb ?? 200}
              onChange={v => onChange('tools.officePptxMaxUncompressedMb', Number(v))} />
            <HelpText>PPTX の ZIP 展開後の合計サイズ上限（ZIP bomb 検知用、デフォルト: 200 MB）</HelpText>
          </div>
        </div>
      )}
    </div>
  );
}
