/**
 * 過渡期開發工具。拔掉 DEV 模式時，刪除此檔案與所有引用即可。
 * 包含：dev_mode 切換、Chrome 擴充同步、手動 session 匯入。
 */
import { useEffect, useState } from 'react'
import { api, ApiError } from '../api/client'
import { storage } from '../lib/storage'
import {
  isExtensionBridgePresent,
  pingExtensionBridge,
  requestExtensionSync,
  waitForExtensionBridge,
} from '../lib/extensionSync'
import {
  connectionModeDescription,
  connectionModeLabel,
  connectionReadyLabel,
} from '../lib/connectionMode'
import type { ImportThreadsAccountSessionData, ThreadsAccountConnectionData } from '../types/api'
import { useOnboarding } from '../onboarding/OnboardingContext'
import { useThreadsAccount } from '../threads/ThreadsAccountContext'
import { ExtensionInstallCard } from './ExtensionInstallCard'
import { Badge, Button, ChoiceCard, Field, Notice, Textarea } from './ui'

type DevToolsPanelProps = {
  accountId: string
  connection: ThreadsAccountConnectionData | null
  workspaceLoading?: boolean
  onConnectionChange: (data: ThreadsAccountConnectionData) => void
  onMessage: (message: string) => void
  onError: (message: string) => void
}

export function DevToolsPanel({
  accountId,
  connection,
  workspaceLoading,
  onConnectionChange,
  onMessage,
  onError,
}: DevToolsPanelProps) {
  const { refresh: refreshOnboarding } = useOnboarding()
  const { refresh: refreshAccounts } = useThreadsAccount()
  const [open, setOpen] = useState(false)
  const [busy, setBusy] = useState(false)
  const [extensionReady, setExtensionReady] = useState(false)
  const [syncBusy, setSyncBusy] = useState(false)
  const [manualState, setManualState] = useState('')
  const [importBusy, setImportBusy] = useState(false)
  const [showManualImport, setShowManualImport] = useState(false)

  const prefs = connection?.prefs

  useEffect(() => {
    let cancelled = false
    const onBridgeMessage = (event: MessageEvent) => {
      if (event.source !== window) return
      if (event.data?.type === 'HAIXUN_EXTENSION_READY') setExtensionReady(true)
    }
    window.addEventListener('message', onBridgeMessage)
    const timer = window.setInterval(() => {
      if (cancelled) return
      if (isExtensionBridgePresent()) {
        setExtensionReady(true)
        return
      }
      pingExtensionBridge()
    }, 1500)
    pingExtensionBridge()
    waitForExtensionBridge(6000).then((ready) => {
      if (!cancelled && ready) setExtensionReady(true)
    })
    return () => {
      cancelled = true
      window.removeEventListener('message', onBridgeMessage)
      window.clearInterval(timer)
    }
  }, [])

  const saveDevMode = async (devMode: boolean) => {
    setBusy(true)
    onError('')
    onMessage('')
    try {
      const data = await api.patch<ThreadsAccountConnectionData>(
        `/api/v1/threads-accounts/${encodeURIComponent(accountId)}/connection`,
        { dev_mode: devMode },
        { auth: true },
      )
      onConnectionChange(data)
      onMessage(devMode ? '已切換為開發模式（爬蟲）' : '已切換為正式模式（API）')
      await refreshOnboarding()
    } catch (e) {
      onError(e instanceof ApiError ? e.message : '儲存失敗')
    } finally {
      setBusy(false)
    }
  }

  const reloadConnection = async () => {
    const data = await api.get<ThreadsAccountConnectionData>(
      `/api/v1/threads-accounts/${encodeURIComponent(accountId)}/connection`,
      { auth: true },
    )
    onConnectionChange(data)
    return data
  }

  const syncChromeSession = async () => {
    setSyncBusy(true)
    onError('')
    onMessage('')
    try {
      const ready = extensionReady || isExtensionBridgePresent() || (await waitForExtensionBridge(4000))
      if (!ready) {
        throw new Error(
          '找不到巡樓 Chrome 擴充。請到 chrome://extensions 載入 extension/haixun-threads-sync，按「重新載入」後刷新此頁（F5）',
        )
      }
      setExtensionReady(true)

      await api.get('/api/v1/members/me', { auth: true })
      const accessToken = storage.getAccessToken()
      if (!accessToken) throw new Error('登入狀態已失效，請重新登入')

      const result = await requestExtensionSync({
        accountId,
        accessToken,
        serverUrl: window.location.origin,
      })
      if (result.success === false || result.valid === false) {
        throw new Error(result.message || 'Chrome session 同步失敗')
      }
      onMessage(result.message || 'Chrome session 已同步')
      await reloadConnection()
      await refreshAccounts()
      await refreshOnboarding()
    } catch (e) {
      onError(e instanceof ApiError ? e.message : e instanceof Error ? e.message : 'Chrome session 同步失敗')
    } finally {
      setSyncBusy(false)
    }
  }

  const importManualSession = async () => {
    const trimmed = manualState.trim()
    if (!trimmed) {
      onError('請貼上 Playwright storage state JSON')
      return
    }
    setImportBusy(true)
    onError('')
    onMessage('')
    try {
      JSON.parse(trimmed)
      const data = await api.post<ImportThreadsAccountSessionData>(
        `/api/v1/threads-accounts/${encodeURIComponent(accountId)}/session/import`,
        { storageState: trimmed },
        { auth: true },
      )
      if (!data.valid) throw new Error(data.message || 'Session 驗證失敗')
      setManualState('')
      onMessage(data.message || 'Session 已匯入')
      await reloadConnection()
      await refreshAccounts()
      await refreshOnboarding()
    } catch (e) {
      if (e instanceof SyntaxError) {
        onError('JSON 格式不正確，請貼上完整的 Playwright storage state')
      } else {
        onError(e instanceof ApiError ? e.message : e instanceof Error ? e.message : '匯入失敗')
      }
    } finally {
      setImportBusy(false)
    }
  }

  return (
    <div className="ac-dev-panel grid gap-3 p-5 md:p-6">
      <button
        type="button"
        className="flex w-full items-center justify-between gap-2 text-left"
        onClick={() => setOpen((v) => !v)}
      >
        <div>
          <p className="text-sm font-bold text-ink">開發工具（過渡期）</p>
          <p className="ac-hint mt-1">
            爬蟲與 Chrome 同步。正式上線後會移除，平常請用上方 Threads API。
          </p>
        </div>
        <span className="shrink-0 text-sm text-muted">{open ? '收起 ▴' : '展開 ▾'}</span>
      </button>

      {open && prefs ? (
        <div className="grid gap-4 border-t-2 border-line pt-4">
          <div className="flex flex-wrap items-center gap-2">
            <Badge tone={prefs.dev_mode ? 'warning' : 'neutral'}>
              {connectionModeLabel(prefs.dev_mode)}
            </Badge>
            <Badge
              tone={
                prefs.dev_mode
                  ? connection.browser_connected
                    ? 'success'
                    : 'warning'
                  : 'neutral'
              }
            >
              {prefs.dev_mode
                ? connectionReadyLabel(true, connection.browser_connected, false)
                : '未啟用爬蟲'}
            </Badge>
          </div>

          <p className="text-sm text-ink-secondary">{connectionModeDescription(prefs.dev_mode)}</p>

          <div className="grid gap-3 sm:grid-cols-2">
            <ChoiceCard
              title="關閉開發模式"
              hint="回到 Threads API"
              active={!prefs.dev_mode}
              disabled={busy || workspaceLoading || !prefs.dev_mode}
              onClick={() => saveDevMode(false)}
            />
            <ChoiceCard
              title="開啟開發模式"
              hint="全部走爬蟲"
              active={prefs.dev_mode}
              disabled={busy || workspaceLoading || prefs.dev_mode}
              onClick={() => saveDevMode(true)}
            />
          </div>

          {prefs.dev_mode ? (
            <>
              <div className="flex flex-wrap items-center gap-2">
                <Badge tone={extensionReady ? 'success' : 'warning'}>
                  {extensionReady ? '擴充已偵測' : '尚未偵測擴充'}
                </Badge>
              </div>
              <div className="flex flex-wrap gap-2">
                <Button onClick={syncChromeSession} disabled={syncBusy || workspaceLoading}>
                  {syncBusy ? '同步中…' : '從 Chrome 同步 Session'}
                </Button>
                <Button variant="ghost" onClick={() => setShowManualImport((v) => !v)}>
                  {showManualImport ? '收起手動匯入' : '手動貼 JSON'}
                </Button>
              </div>
              {showManualImport ? (
                <div className="ac-slot grid gap-3 p-4">
                  <Field label="Playwright storageState JSON">
                    <Textarea
                      mono
                      rows={6}
                      value={manualState}
                      onChange={(e) => setManualState(e.target.value)}
                      placeholder='{"cookies":[...],"origins":[...]}'
                    />
                  </Field>
                  <Button onClick={importManualSession} disabled={importBusy || workspaceLoading}>
                    {importBusy ? '匯入中…' : '匯入 Session'}
                  </Button>
                </div>
              ) : null}
              {!extensionReady ? (
                <>
                  <Notice
                    tone="warning"
                    title="擴充未就緒"
                    message="安裝擴充後到 chrome://extensions 重新載入，再按 F5 刷新此頁。巡樓網址須與擴充選項一致（localhost 與 127.0.0.1 也要一致）。"
                  />
                  <ExtensionInstallCard compact showSteps={false} />
                </>
              ) : null}
              <div className="ac-slot px-4 py-3">
                <p className="ac-hint">
                  診斷：頁面 {window.location.origin}｜JWT{' '}
                  {storage.getAccessToken() ? '有' : '無'}｜後端目標{' '}
                  {window.location.port === '5173' ||
                  window.location.port === '4173' ||
                  window.location.port === '3000'
                    ? `${window.location.protocol}//${window.location.hostname === 'localhost' ? '127.0.0.1' : window.location.hostname}:8890`
                    : window.location.origin}
                </p>
              </div>
            </>
          ) : (
            <Notice
              tone="info"
              title="開發模式已關閉"
              message="目前使用上方 Threads API 連線。只有本機除錯時才需開啟。"
            />
          )}
        </div>
      ) : null}
    </div>
  )
}