import React from 'react'
import { createRoot } from 'react-dom/client'
import browser from 'webextension-polyfill'
import { getSettings, saveSettings, type ExtensionSettings } from '../lib/settings'
import './styles.css'

type MediaCandidate = {
  id: string
  url: string
  kind: 'mp4' | 'm3u8' | 'm3u' | 'hls' | 'unknown'
  referer: string
  detectedAt: number
}

function App(): JSX.Element {
  const [settings, setSettings] = React.useState<ExtensionSettings | null>(null)
  const [status, setStatus] = React.useState('')
  const [mediaItems, setMediaItems] = React.useState<MediaCandidate[]>([])

  React.useEffect(() => {
    void getSettings().then(setSettings)
  }, [])

  React.useEffect(() => {
    let timer: number | null = null
    const loadMedia = async () => {
      const response = (await browser.runtime.sendMessage({ type: 'media:list' })) as {
        ok?: boolean
        items?: MediaCandidate[]
      }
      if (response?.ok && Array.isArray(response.items)) {
        setMediaItems(response.items.slice(0, 10))
      }
    }
    void loadMedia()
    timer = window.setInterval(() => {
      void loadMedia()
    }, 2000)

    return () => {
      if (timer !== null) window.clearInterval(timer)
    }
  }, [])

  const update = <K extends keyof ExtensionSettings>(key: K, value: ExtensionSettings[K]) => {
    setSettings((prev) => (prev ? { ...prev, [key]: value } : prev))
  }

  const onToggleExtension = async (enabled: boolean) => {
    if (!settings) return
    const next = { ...settings, extensionStatus: enabled }
    setSettings(next)
    await saveSettings({ extensionStatus: enabled })
    setStatus(enabled ? 'Extension ON' : 'Extension OFF')
    window.setTimeout(() => setStatus(''), 1200)
  }

  const onSave = async () => {
    if (!settings) return
    await saveSettings(settings)
    setStatus('Saved')
    window.setTimeout(() => setStatus(''), 1200)
  }

  const onOpenSettings = async () => {
    const url = browser.runtime.getURL('src/config/index.html')
    await browser.tabs.create({ url })
  }

  const onOpenHistory = async () => {
    const url = browser.runtime.getURL('src/history/index.html')
    await browser.tabs.create({ url })
  }

  const onSendActiveTabByYtDlp = async () => {
    const result = (await browser.runtime.sendMessage({
      type: 'page:enqueue-ytdlp',
    })) as { ok?: boolean; error?: string }
    setStatus(result?.ok ? 'Active tab sent to gdown (yt-dlp)' : `Send failed: ${result?.error || 'unknown error'}`)
    window.setTimeout(() => setStatus(''), 1800)
  }

  const onSendMedia = async (item: MediaCandidate) => {
    const result = (await browser.runtime.sendMessage({
      type: 'media:enqueue',
      url: item.url,
      referer: item.referer || '',
    })) as { ok?: boolean; error?: string }
    setStatus(result?.ok ? 'Media sent to gdown' : `Send failed: ${result?.error || 'unknown error'}`)
    window.setTimeout(() => setStatus(''), 1600)
  }

  const onClearMedia = async () => {
    await browser.runtime.sendMessage({ type: 'media:clear' })
    setMediaItems([])
    setStatus('Captured media cleared')
    window.setTimeout(() => setStatus(''), 1200)
  }

  if (!settings) {
    return <div className="container">Loading...</div>
  }

  return (
    <div className="container">
      <h1>Gomdown Helper</h1>

      <div className="field">
        <label>RPC Secret</label>
        <input
          type="text"
          value={settings.motrixAPIkey}
          onChange={(e) => update('motrixAPIkey', e.target.value)}
          placeholder="aria2 rpc secret"
        />
      </div>

      <div className="field">
        <label>RPC Port</label>
        <input
          type="number"
          value={settings.motrixPort}
          onChange={(e) => update('motrixPort', Number(e.target.value || 16800))}
        />
      </div>

      <label className="toggle">
        Extension Enabled
        <input
          type="checkbox"
          checked={settings.extensionStatus}
          onChange={(e) => {
            void onToggleExtension(e.target.checked)
          }}
        />
      </label>

      <label className="toggle">
        Use Native Host
        <input
          type="checkbox"
          checked={settings.useNativeHost}
          onChange={(e) => update('useNativeHost', e.target.checked)}
        />
      </label>

      <label className="toggle">
        Activate gdown App
        <input
          type="checkbox"
          checked={settings.activateAppOnDownload}
          onChange={(e) => update('activateAppOnDownload', e.target.checked)}
        />
      </label>

      <button onClick={onSave}>Save</button>
      <button onClick={onOpenSettings}>Settings</button>
      <button onClick={onOpenHistory}>History</button>
      <button onClick={() => void onSendActiveTabByYtDlp()}>Send Active Tab (yt-dlp)</button>

      <div className="media-panel">
        <div className="media-head">
          <strong>Captured Media</strong>
          <button className="mini ghost" onClick={onClearMedia}>Clear</button>
        </div>
        {mediaItems.length === 0 ? (
          <div className="empty">No media captured yet</div>
        ) : (
          <div className="media-list">
            {mediaItems.map((item) => (
              <div key={item.id} className="media-item">
                <div className="media-meta">
                  <span className="kind">{item.kind.toUpperCase()}</span>
                  <span className="url">{item.url}</span>
                </div>
                <button className="mini" onClick={() => void onSendMedia(item)}>Add</button>
              </div>
            ))}
          </div>
        )}
      </div>
      <div className="status">{status}</div>
    </div>
  )
}

createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
)
