import { useEffect, useRef, useState, type ChangeEvent, type FormEvent } from 'react'
import { createAccount, getTask, importCSV, runTask, testAccounts, type TaskDetail as TaskDetailData } from '../api'
import { connectTaskWS, type TaskEvent } from '../ws'
import { StatusBadge } from '../components/StatusBadge'

const emptyAccount = { src_login: '', src_pass: '', dst_login: '', dst_pass: '' }

export function TaskDetail({ id }: { id: number }) {
  const [data, setData] = useState<TaskDetailData | null>(null)
  const [notFound, setNotFound] = useState(false)
  const [log, setLog] = useState<{ type: string; text: string }[]>([])
  const [form, setForm] = useState(emptyAccount)
  const [busy, setBusy] = useState<'test' | 'run' | 'add' | 'import' | null>(null)
  const [error, setError] = useState<string | null>(null)
  const fileInputRef = useRef<HTMLInputElement>(null)

  function reload() {
    getTask(id)
      .then((d) => {
        setData(d)
        setNotFound(false)
      })
      .catch(() => setNotFound(true))
  }

  useEffect(reload, [id])

  useEffect(
    () =>
      connectTaskWS(id, (ev: TaskEvent) => {
        setLog((l) => [{ type: ev.type, text: JSON.stringify(ev.data) }, ...l].slice(0, 300))
        if (['account_started', 'account_test', 'account_done', 'progress', 'run_started', 'run_done', 'error'].includes(ev.type)) {
          reload()
        }
      }),
    [id],
  )

  async function submitAccount(e: FormEvent) {
    e.preventDefault()
    setBusy('add')
    setError(null)
    try {
      await createAccount(id, form)
      setForm(emptyAccount)
      reload()
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to add account')
    } finally {
      setBusy(null)
    }
  }

  async function onFileChosen(e: ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0]
    if (!file) return
    setBusy('import')
    setError(null)
    try {
      await importCSV(id, file)
      reload()
    } catch (err) {
      setError(err instanceof Error ? err.message : 'CSV import failed')
    } finally {
      setBusy(null)
      if (fileInputRef.current) fileInputRef.current.value = ''
    }
  }

  async function onTest() {
    setBusy('test')
    setError(null)
    try {
      await testAccounts(id)
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to start connection tests')
    } finally {
      setBusy(null)
    }
  }

  async function onRun() {
    setBusy('run')
    setError(null)
    try {
      await runTask(id)
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to start run')
    } finally {
      setBusy(null)
    }
  }

  if (notFound) {
    return (
      <div className="panel">
        <p>Task #{id} not found.</p>
        <a className="crumb" href="#/">
          ← back to tasks
        </a>
      </div>
    )
  }

  if (!data) {
    return <div className="muted-note">loading task #{id}…</div>
  }

  const { task, accounts } = data
  const allTested = accounts.length > 0 && accounts.every((a) => a.test_src_status === 'ok' && a.test_dst_status === 'ok')
  const totals = accounts.reduce(
    (acc, a) => ({ copied: acc.copied + a.copied, skipped: acc.skipped + a.skipped, errors: acc.errors + a.errors }),
    { copied: 0, skipped: 0, errors: 0 },
  )

  return (
    <>
      <div className="page-head">
        <div>
          <a className="crumb" href="#/">
            ← all tasks
          </a>
          <h1 className="page-title" style={{ marginTop: 6 }}>
            {task.name} <span className="idx">/// task #{task.id}</span>
          </h1>
        </div>
        <StatusBadge status={task.status} />
      </div>

      <div className="panel">
        <span className="panel-label">Run control</span>
        <div className="stat-row">
          <div className="stat ok">
            <span className="val mono-num">{totals.copied}</span>
            <span className="lbl">copied</span>
          </div>
          <div className="stat info">
            <span className="val mono-num">{totals.skipped}</span>
            <span className="lbl">skipped</span>
          </div>
          <div className="stat fail">
            <span className="val mono-num">{totals.errors}</span>
            <span className="lbl">errors</span>
          </div>
          <div className="stat">
            <span className="val mono-num">{accounts.length}</span>
            <span className="lbl">accounts</span>
          </div>
        </div>
        {error && <div className="error-banner">{error}</div>}
        <div className="btn-row" style={{ marginTop: 16 }}>
          <button className="btn" onClick={onTest} disabled={busy !== null || accounts.length === 0}>
            {busy === 'test' ? 'Testing…' : 'Test connections'}
          </button>
          <button className="btn btn-primary" onClick={onRun} disabled={busy !== null || !allTested}>
            {busy === 'run' ? 'Starting…' : 'Run migration'}
          </button>
          {!allTested && accounts.length > 0 && <span className="hint">run unlocks once every account tests OK on both sides</span>}
        </div>
      </div>

      <div className="panel-grid">
        <div className="panel">
          <span className="panel-label">Add account</span>
          <form onSubmit={submitAccount}>
            <div className="field-row">
              <div className="field">
                <label htmlFor="src_login">Source login</label>
                <input
                  id="src_login"
                  value={form.src_login}
                  onChange={(e) => setForm({ ...form, src_login: e.target.value })}
                  required
                />
              </div>
              <div className="field">
                <label htmlFor="src_pass">Source password</label>
                <input
                  id="src_pass"
                  type="password"
                  value={form.src_pass}
                  onChange={(e) => setForm({ ...form, src_pass: e.target.value })}
                  required
                />
              </div>
            </div>
            <div className="field-row">
              <div className="field">
                <label htmlFor="dst_login">Destination login</label>
                <input
                  id="dst_login"
                  value={form.dst_login}
                  onChange={(e) => setForm({ ...form, dst_login: e.target.value })}
                  required
                />
              </div>
              <div className="field">
                <label htmlFor="dst_pass">Destination password</label>
                <input
                  id="dst_pass"
                  type="password"
                  value={form.dst_pass}
                  onChange={(e) => setForm({ ...form, dst_pass: e.target.value })}
                  required
                />
              </div>
            </div>
            <div className="btn-row">
              <button className="btn btn-primary" disabled={busy !== null}>
                {busy === 'add' ? 'Adding…' : 'Add account'}
              </button>
            </div>
          </form>

          <div className="divider-label">or bulk import</div>
          <div className="upload-row">
            <button className="btn file-btn" disabled={busy !== null}>
              {busy === 'import' ? 'Importing…' : 'Upload CSV'}
              <input ref={fileInputRef} type="file" accept=".csv,text/csv" onChange={onFileChosen} disabled={busy !== null} />
            </button>
            <span className="hint">columns: src_login, src_pass, dst_login, dst_pass</span>
          </div>
        </div>

        <div className="panel">
          <span className="panel-label">Event log</span>
          <div className="log-pane">
            {log.length === 0 ? (
              <div className="log-empty">awaiting events over websocket…</div>
            ) : (
              log.map((l, i) => (
                <div className="log-line" key={i}>
                  <span className="tag">{l.type}</span>
                  <span className="payload">{l.text}</span>
                </div>
              ))
            )}
          </div>
        </div>
      </div>

      <div className="panel">
        <span className="panel-label">Accounts ({accounts.length})</span>
        <div className="tbl-wrap">
          <table className="tbl">
            <thead>
              <tr>
                <th>Source</th>
                <th>Destination</th>
                <th>Src test</th>
                <th>Dst test</th>
                <th>Status</th>
                <th>Copied</th>
                <th>Skipped</th>
                <th>Errors</th>
              </tr>
            </thead>
            <tbody>
              {accounts.length === 0 ? (
                <tr className="empty-row">
                  <td colSpan={8}>no accounts yet — add one or import a CSV above</td>
                </tr>
              ) : (
                accounts.map((a) => (
                  <tr key={a.id}>
                    <td>{a.src_login}</td>
                    <td>{a.dst_login}</td>
                    <td>
                      <StatusBadge status={a.test_src_status} />
                    </td>
                    <td>
                      <StatusBadge status={a.test_dst_status} />
                    </td>
                    <td>
                      <StatusBadge status={a.status} />
                    </td>
                    <td className="num-cell">{a.copied}</td>
                    <td className="num-cell">{a.skipped}</td>
                    <td className="num-cell">{a.errors}</td>
                  </tr>
                ))
              )}
            </tbody>
          </table>
        </div>
      </div>
    </>
  )
}
