import { useCallback, useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import { api } from '../api/client'
import { ApiError } from '../api/client'
import { useAuth } from '../auth/AuthContext'
import {
  Button,
  Card,
  ErrorText,
  Field,
  Input,
  PageTitle,
  ProgressBar,
  StatusBadge,
  Table,
  TableAction,
  TablePanel,
  TableShell,
  Textarea,
} from '../components/ui'
import { isTerminalJobStatus, jobStatusBadgeClass, jobStatusLabel } from '../lib/jobStatus'
import type { JobData, Pagination } from '../types/api'

export function JobsPage() {
  const { uid } = useAuth()
  const [jobs, setJobs] = useState<JobData[]>([])
  const [pagination, setPagination] = useState<Pagination | null>(null)
  const [error, setError] = useState('')
  const [templateType, setTemplateType] = useState('demo_long_task')
  const [scope, setScope] = useState('user')
  const [scopeId, setScopeId] = useState(uid)
  const [payload, setPayload] = useState('{}')

  const load = useCallback(async () => {
    setError('')
    try {
      const data = await api.get<{ list: JobData[]; pagination: Pagination }>('/api/v1/jobs', {
        auth: true,
        query: { page: 1, pageSize: 20, scope, scope_id: scopeId },
      })
      setJobs(data.list)
      setPagination(data.pagination)
    } catch (e) {
      setError(e instanceof ApiError ? e.message : '載入失敗')
    }
  }, [scope, scopeId])

  useEffect(() => {
    if (uid) setScopeId(uid)
  }, [uid])

  useEffect(() => {
    load()
  }, [load])

  useEffect(() => {
    const hasActive = jobs.some((j) => !isTerminalJobStatus(j.status))
    if (!hasActive) return
    const timer = window.setInterval(load, 3000)
    return () => window.clearInterval(timer)
  }, [jobs, load])

  const create = async () => {
    setError('')
    try {
      await api.post(
        '/api/v1/jobs',
        {
          template_type: templateType,
          scope,
          scope_id: scopeId,
          payload: JSON.parse(payload),
        },
        { auth: true },
      )
      await load()
    } catch (e) {
      setError(e instanceof ApiError ? e.message : '建立失敗')
    }
  }

  const cancel = async (id: string) => {
    await api.post(`/api/v1/jobs/${id}/cancel`, { reason: 'ui cancel' }, { auth: true })
    await load()
  }

  const retry = async (id: string) => {
    await api.post(`/api/v1/jobs/${id}/retry`, {}, { auth: true })
    await load()
  }

  return (
    <div>
      <PageTitle title="Jobs" subtitle="建立、列表、取消、重試" />
      <Card className="ac-bulletin--island mb-4 text-sm text-ink-secondary">
        <p className="font-semibold text-ink">怎麼知道任務有沒有在跑？</p>
        <ul className="mt-2 list-inside list-disc space-y-1">
          <li>
            啟動 API（<code className="rounded-[var(--radius-sm)] bg-surface px-1.5 py-0.5">make run</code>）只會建立預設模板{' '}
            <code className="rounded-[var(--radius-sm)] bg-surface px-1.5 py-0.5">demo_long_task</code>，不會自動產生執行紀錄。
          </li>
          <li>按下方「建立背景任務」或到「排程」頁建立 cron，才會真正產生一筆 Job。</li>
          <li>
            看列表「狀態」：<strong>執行中</strong> = 正在跑；<strong>已排隊 / 等待中</strong> = 還沒被
            worker 接手（確認 Redis 與 gateway 的 <code className="rounded-[var(--radius-sm)] bg-surface px-1.5 py-0.5">JobWorker.Enabled</code>）。
          </li>
          <li>點「查看任務詳情」可看進度與事件；有進行中任務時此頁每 3 秒自動刷新。</li>
        </ul>
      </Card>
      <Card className="mb-4 space-y-3">
        <div className="grid gap-3 md:grid-cols-3">
          <Field label="Template Type">
            <Input value={templateType} onChange={(e) => setTemplateType(e.target.value)} />
          </Field>
          <Field label="Scope">
            <Input value={scope} onChange={(e) => setScope(e.target.value)} />
          </Field>
          <Field label="Scope ID">
            <Input value={scopeId} onChange={(e) => setScopeId(e.target.value)} />
          </Field>
        </div>
        <Field label="Payload JSON">
          <Textarea rows={3} value={payload} onChange={(e) => setPayload(e.target.value)} />
        </Field>
        <div className="flex gap-2">
          <Button onClick={create}>建立背景任務</Button>
          <Button variant="ghost" onClick={load}>
            重新載入任務列表
          </Button>
        </div>
        <ErrorText message={error} />
      </Card>
      <TablePanel title="服務中心任務列表" count={pagination?.total}>
        <TableShell>
          <Table minWidth="48rem">
            <thead>
              <tr>
                <th>ID</th>
                <th>狀態</th>
                <th>進度</th>
                <th>模板</th>
                <th>操作</th>
              </tr>
            </thead>
            <tbody>
              {jobs.map((j) => (
                <tr key={j.id}>
                  <td>
                    <div className="font-mono text-xs text-ink-secondary">{j.id.slice(0, 8)}…</div>
                    <Link
                      to={`/jobs/${j.id}`}
                      className="ac-table-action ac-table-action--link mt-2 inline-flex"
                    >
                      查看詳情
                    </Link>
                  </td>
                  <td>
                    <StatusBadge className={jobStatusBadgeClass(j.status)}>
                      {jobStatusLabel(j.status)}
                    </StatusBadge>
                    <span className="mt-1 block text-xs text-muted">{j.phase}</span>
                  </td>
                  <td>
                    <div className="min-w-[7rem]">
                      <ProgressBar value={j.progress.percentage} />
                      <p className="mt-1 text-xs font-bold text-ink-secondary">
                        {j.progress.percentage}%
                      </p>
                      {j.progress.summary ? (
                        <p className="mt-0.5 text-xs leading-relaxed text-muted">{j.progress.summary}</p>
                      ) : null}
                    </div>
                  </td>
                  <td className="font-semibold">{j.template_type}</td>
                  <td>
                    <div className="flex flex-wrap gap-1.5">
                      <TableAction variant="danger" onClick={() => cancel(j.id)}>
                        取消
                      </TableAction>
                      <TableAction onClick={() => retry(j.id)}>重試</TableAction>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </Table>
        </TableShell>
      </TablePanel>
    </div>
  )
}