'use client'
import { useEffect, useMemo, useState } from 'react'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { Label } from '@/components/ui/label'
import { Input } from '@/components/ui/input'
import { listRepos, listBranches, startDeploy, type Repo } from '@/lib/api'
import { useDeploymentWS } from '@/lib/use-deployment-ws'

const GO_STAGES = ['git fetch', 'git checkout', 'git pull', 'go build', 'start container']
const PHP_STAGES = ['git fetch', 'git checkout', 'git pull', 'composer install', 'start container']

export function Dashboard() {
  const [repos, setRepos] = useState<Repo[]>([])
  const [repo, setRepo] = useState<string>('')
  const [branches, setBranches] = useState<string[]>([])
  const [branch, setBranch] = useState<string>('')
  const [username, setUsername] = useState('')
  const [password, setPassword] = useState('')
  const [hostPort, setHostPort] = useState<string>('')
  const [envLines, setEnvLines] = useState<string>('KEY=value')
  const [deploymentId, setDeploymentId] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [deploying, setDeploying] = useState(false)

  const { events, state } = useDeploymentWS(deploymentId)

  useEffect(() => {
    listRepos().then((r) => {
      setRepos(r)
      if (r.length) setRepo(r[0].name)
    }).catch((e) => setError(String(e)))
  }, [])

  useEffect(() => {
    if (!repo) return
    listBranches(repo).then((b) => {
      setBranches(b)
      if (b.length) setBranch(b[0])
    }).catch(() => setBranches([]))
  }, [repo])

  const stages = useMemo(() => {
    const r = repos.find((x) => x.name === repo)
    return r?.name === 'api-gateway' ? PHP_STAGES : GO_STAGES
  }, [repo, repos])

  async function deploy() {
    setError(null)
    setDeploying(true)
    try {
      const env: Record<string, string> = {}
      for (const line of envLines.split('\n')) {
        const t = line.trim()
        if (!t || !t.includes('=')) continue
        const i = t.indexOf('=')
        env[t.slice(0, i).trim()] = t.slice(i + 1).trim()
      }
      const { id } = await startDeploy({
        repository: repo,
        branch,
        username,
        password,
        env: Object.keys(env).length ? env : undefined,
        hostPort: hostPort ? Number(hostPort) : undefined,
      })
      setDeploymentId(id)
    } catch (e) {
      setError(String(e))
    } finally {
      setDeploying(false)
    }
  }

  const stageDone: Record<string, 'pending' | 'ok' | 'failed' | 'in_progress'> = {}
  for (const s of stages) stageDone[s] = 'pending'
  let lastDone: string | null = null
  for (const e of events) {
    if (e.kind === 'progress' && e.stage && stages.includes(e.stage)) {
      if (e.state === 'FAILED') stageDone[e.stage] = 'failed'
      else stageDone[e.stage] = 'ok'
      lastDone = e.stage
    }
  }
  if (lastDone) {
    const idx = stages.indexOf(lastDone)
    if (idx >= 0 && idx + 1 < stages.length && stageDone[stages[idx + 1]] === 'pending') {
      stageDone[stages[idx + 1]] = 'in_progress'
    }
  }

  return (
    <div className="container py-8">
      <div className="mb-6">
        <h1 className="text-2xl font-semibold tracking-tight">Quick Deploy</h1>
        <p className="text-sm text-muted-foreground">
          Deploy a single service. For sandboxes with route overrides, use the Sandboxes tab.
        </p>
      </div>

      <div className="grid gap-6 lg:grid-cols-[360px_1fr]">
        <Card>
          <CardHeader>
            <CardTitle>Deploy a branch</CardTitle>
            <CardDescription>Credentials are forwarded to the agent for this deploy only.</CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="space-y-1.5">
              <Label>Repository</Label>
              <Select value={repo} onValueChange={setRepo}>
                <SelectTrigger><SelectValue placeholder="Pick a repo" /></SelectTrigger>
                <SelectContent>
                  {repos.map((r) => (
                    <SelectItem key={r.name} value={r.name}>{r.name} <span className="text-muted-foreground">· {r.node}</span></SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-1.5">
              <Label>Branch</Label>
              <Select value={branch} onValueChange={setBranch}>
                <SelectTrigger><SelectValue placeholder="Pick a branch" /></SelectTrigger>
                <SelectContent>
                  {branches.map((b) => (
                    <SelectItem key={b} value={b}>{b}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="hp">Host port (optional)</Label>
              <Input id="hp" value={hostPort} onChange={(e) => setHostPort(e.target.value)} placeholder="9001" />
              <p className="text-xs text-muted-foreground">Maps the container's exposed port to this host port. Leave blank to skip port publishing.</p>
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="env">Env vars (KEY=value per line)</Label>
              <textarea
                id="env"
                className="flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm font-mono shadow-sm"
                value={envLines}
                onChange={(e) => setEnvLines(e.target.value)}
              />
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="u">Bitbucket username</Label>
              <Input id="u" value={username} onChange={(e) => setUsername(e.target.value)} autoComplete="username" />
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="p">Bitbucket password</Label>
              <Input id="p" type="password" value={password} onChange={(e) => setPassword(e.target.value)} autoComplete="current-password" />
            </div>
            {error && <p className="text-sm text-destructive">{error}</p>}
            <Button onClick={deploy} disabled={!repo || !branch || !username || !password || deploying} className="w-full">
              {deploying ? 'Starting…' : 'Deploy'}
            </Button>
          </CardContent>
        </Card>

        <div className="space-y-6">
          {deploymentId ? (
            <Card>
              <CardHeader>
                <div className="flex items-center justify-between">
                  <div>
                    <CardTitle className="font-mono text-base">{deploymentId}</CardTitle>
                    <CardDescription>{repo} · {branch}</CardDescription>
                  </div>
                  <Badge variant={state === 'RUNNING' ? 'success' : state === 'FAILED' ? 'destructive' : 'secondary'}>
                    {state}
                  </Badge>
                </div>
              </CardHeader>
              <CardContent className="space-y-4">
                <ol className="space-y-1.5 text-sm">
                  {stages.map((s) => {
                    const v = stageDone[s]
                    return (
                      <li key={s} className="flex items-center gap-3">
                        <span className={
                          v === 'ok' ? 'text-emerald-600' :
                          v === 'failed' ? 'text-red-600' :
                          v === 'in_progress' ? 'text-amber-600' :
                          'text-muted-foreground'
                        }>
                          {v === 'ok' ? '✓' : v === 'failed' ? '✗' : v === 'in_progress' ? '…' : '·'}
                        </span>
                        <span className={v === 'in_progress' ? 'font-medium' : ''}>{s}</span>
                      </li>
                    )
                  })}
                </ol>
                <LogView events={events} />
              </CardContent>
            </Card>
          ) : (
            <Card>
              <CardHeader>
                <CardTitle>How this works</CardTitle>
              </CardHeader>
              <CardContent className="text-sm text-muted-foreground space-y-2">
                <p>The agent on the chosen VM does <code className="rounded bg-zinc-100 px-1">git fetch → checkout → pull</code>, builds the service, and starts the container.</p>
                <p>For PHP gateways we skip the build — the apache container serves the bind-mounted repo on the host port you specify.</p>
                <p>Credentials are used once for the git operation, then discarded.</p>
              </CardContent>
            </Card>
          )}
        </div>
      </div>
    </div>
  )
}

function LogView({ events }: { events: { kind: string; line?: string; stage?: string; backfill?: boolean }[] }) {
  return (
    <pre className="h-72 overflow-auto rounded-md border bg-zinc-950 p-3 text-xs text-zinc-100 font-mono">
      {events
        .filter((e) => e.kind === 'log' && e.line)
        .slice(-500)
        .map((e, i) => (
          <div key={i} className="whitespace-pre-wrap">{e.line}</div>
        ))}
    </pre>
  )
}
