'use client'

import { useState, useCallback } from 'react'
import Link from 'next/link'
import { useFlowRun } from '@/hooks/useFlowRun'
import StreamingTerminal from '@/components/StreamingTerminal'
import ConfirmDialog from '@/components/ConfirmDialog'

// One panel runs either flow; we switch step-list + description based on the
// currently active or last-triggered action. Wording mirrors the existing
// /settings/backups → server-backup-section so the two entry points stay
// consistent. The actual work in both flows runs out-of-band via systemd
// (server-backup.service) — the ops-agent flow just kicks it off and tails
// the resulting log / status file.

type Kind = 'backup' | 'restore'

type FlowSpec = {
  flowKey: string
  buttonLabel: string
  shortDescription: string
  steps: string[]
  confirmTitle: string
  confirmBody: string
}

const FLOWS: Record<Kind, FlowSpec> = {
  backup: {
    flowKey: 'server_backup_full',
    buttonLabel: 'Backup now',
    shortDescription:
      'Volledige server-backup: pg_dumpall van alle databases + restic snapshot naar NAS én Backblaze B2 (Object Lock). Draait dagelijks via timer; deze knop triggert handmatig.',
    steps: [
      'trigger_server_backup (systemctl start server-backup.service)',
      'tail_backup_log_today (live log mee-stream)',
      'read_backup_status (lees status.json met repo-totalen + duur)',
    ],
    confirmTitle: 'Trigger server backup',
    confirmBody:
      'flow: server_backup_full\n\nSteps:\n  1. trigger_server_backup (systemctl start server-backup.service)\n  2. tail_backup_log_today\n  3. read_backup_status\n\nThe actual work happens in systemd; this flow kicks it off and tails the log.',
  },
  restore: {
    flowKey: 'server_backup_restore_test',
    buttonLabel: 'Run restore test',
    shortDescription:
      'Non-destructieve restore-test: haalt de laatste snapshot uit de NAS-repo terug naar /tmp/restore-test en verifieert dat kritieke files er zijn. Raakt niets in de live stack.',
    steps: [
      'trigger_restore_test (restore latest NAS snapshot to /tmp/restore-test/)',
      'read_backup_status (lees assertions + per-file outcome)',
    ],
    confirmTitle: 'Run restore test (NAS)',
    confirmBody:
      'flow: server_backup_restore_test\n\nSteps:\n  1. trigger_restore_test (restore latest NAS snapshot to /tmp/restore-test/)\n  2. read_backup_status\n\nNon-destructive — restores into /tmp only and asserts critical files exist.',
  },
}

export default function FlowPanel() {
  // `displayKind` drives the steps/description card; updated optimistically
  // when the user presses a button so the displayed flow matches the pending
  // confirm. `activeKind` only flips once the flow actually starts.
  const [displayKind, setDisplayKind] = useState<Kind>('backup')
  const [pendingKind, setPendingKind] = useState<Kind | null>(null)
  const [activeKind, setActiveKind] = useState<Kind | null>(null)
  const [completedFlowRunId, setCompletedFlowRunId] = useState<string | null>(null)

  const handleComplete = useCallback((flowRunId: string) => {
    setCompletedFlowRunId(flowRunId)
  }, [])

  const flowRun = useFlowRun(handleComplete)

  const handleClickKind = useCallback((kind: Kind) => {
    setDisplayKind(kind)
    setPendingKind(kind)
  }, [])

  const handleConfirm = useCallback(() => {
    if (pendingKind === null) return
    const kind = pendingKind
    setPendingKind(null)
    setCompletedFlowRunId(null)
    setActiveKind(kind)
    flowRun.startFlow(FLOWS[kind].flowKey, false)
  }, [pendingKind, flowRun])

  const handleReset = useCallback(() => {
    flowRun.reset()
    setCompletedFlowRunId(null)
    setActiveKind(null)
  }, [flowRun])

  const spec = FLOWS[displayKind]

  return (
    <div className="space-y-6">
      <div className="rounded-lg border border-border p-5 space-y-4">
        <div>
          <p className="text-sm text-muted-foreground">{spec.shortDescription}</p>
          <p className="mt-1 text-xs text-muted-foreground font-mono">
            flow: {spec.flowKey}
          </p>
        </div>
        <ol className="space-y-1">
          {spec.steps.map((step, i) => (
            <li key={i} className="flex gap-2 text-xs font-mono text-muted-foreground">
              <span className="text-border min-w-[1.5rem]">{i + 1}.</span>
              <span>{step}</span>
            </li>
          ))}
        </ol>
      </div>

      <div className="flex items-center gap-3">
        <button
          onClick={() => handleClickKind('backup')}
          disabled={flowRun.status === 'running'}
          className={`rounded-lg px-4 py-2 text-sm font-medium transition-opacity disabled:opacity-50 ${
            displayKind === 'backup'
              ? 'bg-foreground text-background hover:opacity-90'
              : 'border border-border hover:bg-muted/50'
          }`}
        >
          {FLOWS.backup.buttonLabel}
        </button>
        <button
          onClick={() => handleClickKind('restore')}
          disabled={flowRun.status === 'running'}
          className={`rounded-lg px-4 py-2 text-sm font-medium transition-opacity disabled:opacity-50 ${
            displayKind === 'restore'
              ? 'bg-foreground text-background hover:opacity-90'
              : 'border border-border hover:bg-muted/50'
          }`}
        >
          {FLOWS.restore.buttonLabel}
        </button>
        {flowRun.status !== 'idle' && flowRun.status !== 'running' && (
          <button
            onClick={handleReset}
            className="text-xs text-muted-foreground hover:text-foreground transition-colors"
          >
            Reset
          </button>
        )}
      </div>

      {flowRun.status !== 'idle' && (
        <div className="space-y-2">
          <div className="flex items-center justify-between">
            <span className="text-sm font-medium">
              Output{activeKind ? ` — ${FLOWS[activeKind].buttonLabel}` : ''}
            </span>
            {completedFlowRunId && (
              <Link
                href={`/audit/${completedFlowRunId}`}
                className="text-xs text-muted-foreground hover:text-foreground transition-colors"
              >
                View in audit log →
              </Link>
            )}
          </div>
          <StreamingTerminal
            lines={flowRun.lines}
            status={flowRun.status}
            error={flowRun.error}
          />
        </div>
      )}

      <ConfirmDialog
        open={pendingKind !== null}
        title={pendingKind ? FLOWS[pendingKind].confirmTitle : ''}
        commandPreview={pendingKind ? FLOWS[pendingKind].confirmBody : ''}
        onConfirm={handleConfirm}
        onCancel={() => setPendingKind(null)}
      />
    </div>
  )
}
