'use client';

import { Bot, FileText, Loader2, ShieldCheck, Sparkles } from 'lucide-react';
import { useEffect, useMemo, useState, type ChangeEvent, type ReactNode } from 'react';
import { toast } from 'sonner';
import type { PolicySummary } from '@trustloopguard/sdk';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { createAgent, generateAgentGuardrails } from '@/lib/agents';

interface AgentGuardrailDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onGenerated: (agent: { agentId: string; displayName: string }) => void;
}

interface AgentDraft {
  agentName: string;
  systemPrompt: string;
  samplePrompt: string;
}

type GenerationState = 'editing' | 'creating' | 'generating' | 'ready';

const DEFAULT_DRAFT: AgentDraft = {
  agentName: 'Support bot',
  systemPrompt:
    'You are a customer support agent. Answer billing and product questions, but never promise refunds, legal outcomes, or medical advice. Escalate sensitive cases to a teammate.',
  samplePrompt: 'Customer asks for a guaranteed refund and mentions a medical condition.',
};

const GENERATED_POLICIES = [
  {
    id: 'refund-promise',
    action: 'block',
    severity: 'high',
    summary: 'Stops guaranteed refunds, credits, or compensation promises.',
  },
  {
    id: 'medical-advice',
    action: 'escalate',
    severity: 'critical',
    summary: 'Escalates diagnosis, treatment, medication, and urgent care guidance.',
  },
  {
    id: 'legal-outcome',
    action: 'rewrite',
    severity: 'medium',
    summary: 'Rewrites legal guarantees into neutral handoff language.',
  },
];

export function AgentGuardrailDialog({
  open,
  onOpenChange,
  onGenerated,
}: AgentGuardrailDialogProps) {
  const [draft, setDraft] = useState<AgentDraft>(DEFAULT_DRAFT);
  const [state, setState] = useState<GenerationState>('editing');
  const [agentId, setAgentId] = useState<string | null>(null);
  const [generatedPolicies, setGeneratedPolicies] = useState<PolicySummary[]>([]);

  useEffect(() => {
    if (!open) return;
    setDraft(DEFAULT_DRAFT);
    setState('editing');
    setAgentId(null);
    setGeneratedPolicies([]);
  }, [open]);

  const canGenerate = useMemo(
    () => draft.agentName.trim().length > 0 && draft.systemPrompt.trim().length >= 20,
    [draft],
  );

  function update<K extends keyof AgentDraft>(key: K, value: AgentDraft[K]) {
    setDraft((prev) => ({ ...prev, [key]: value }));
    if (state === 'ready') setState('editing');
  }

  async function runGenerate() {
    if (!canGenerate || state === 'creating' || state === 'generating') return;
    setState('creating');
    setAgentId(null);
    setGeneratedPolicies([]);
    try {
      const agent = await createAgent({
        displayName: draft.agentName,
        systemPrompt: draft.systemPrompt,
      });
      setAgentId(agent.agentId);
      setState('generating');
      const result = await generateAgentGuardrails(agent.agentId);
      setGeneratedPolicies(result.generated);
      setState('ready');
      onGenerated({ agentId: agent.agentId, displayName: agent.displayName });
      toast.success('Agent saved and guardrails generated');
    } catch (err) {
      setState('editing');
      toast.error(describeError(err));
    }
  }

  const busy = state === 'creating' || state === 'generating';
  const previewPolicies = generatedPolicies.length > 0 ? generatedPolicies : GENERATED_POLICIES;

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-h-[92vh] max-w-5xl overflow-auto">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <Bot className="size-5" />
            Add agent guardrails
          </DialogTitle>
          <DialogDescription>
            Paste the agent prompt and start generating a scoped policy set.
          </DialogDescription>
        </DialogHeader>

        <div className="grid gap-6 lg:grid-cols-[minmax(0,0.95fr)_minmax(0,1.05fr)]">
          <fieldset disabled={busy} className="space-y-4">
            <Field label="display name" htmlFor="agent-name">
              <Input
                id="agent-name"
                value={draft.agentName}
                onChange={(event: ChangeEvent<HTMLInputElement>) =>
                  update('agentName', event.target.value)
                }
              />
            </Field>
            <div className="rounded-md border bg-muted/30 p-3">
              <p className="font-mono text-[10px] uppercase tracking-wider text-muted-foreground">
                agent id
              </p>
              <p className="mt-1 font-mono text-sm">{agentId ?? 'Generated by backend on save'}</p>
            </div>
            <Field label="system prompt" htmlFor="system-prompt">
              <Textarea
                id="system-prompt"
                value={draft.systemPrompt}
                onChange={(event: ChangeEvent<HTMLTextAreaElement>) =>
                  update('systemPrompt', event.target.value)
                }
                rows={8}
                className="font-mono leading-relaxed"
              />
            </Field>
            <Field label="sample user prompt" htmlFor="sample-prompt">
              <Textarea
                id="sample-prompt"
                value={draft.samplePrompt}
                onChange={(event: ChangeEvent<HTMLTextAreaElement>) =>
                  update('samplePrompt', event.target.value)
                }
                rows={3}
              />
            </Field>
          </fieldset>

          <div className="space-y-4">
            <div className="rounded-md border bg-muted/30 p-4">
              <div className="flex items-start justify-between gap-4">
                <div>
                  <p className="font-mono text-[10px] uppercase tracking-wider text-muted-foreground">
                    generation status
                  </p>
                  <h3 className="mt-1 text-base font-semibold">
                    {state === 'creating'
                      ? 'Saving agent profile'
                      : state === 'generating'
                        ? 'Generating guardrail policies'
                        : state === 'ready'
                          ? 'Policy draft set ready'
                          : 'Ready to generate'}
                  </h3>
                </div>
                <Badge variant={state === 'ready' ? 'secondary' : 'outline'} className="font-mono">
                  {state}
                </Badge>
              </div>

              <div className="mt-4 space-y-3">
                <Step
                  icon={<FileText className="size-4" />}
                  title="Save agent with backend-generated ID"
                  active={state === 'creating'}
                  complete={state === 'generating' || state === 'ready'}
                />
                <Step
                  icon={<ShieldCheck className="size-4" />}
                  title="Map scope, forbidden claims, and escalation rules"
                  active={state === 'generating'}
                  complete={state === 'ready'}
                />
                <Step
                  icon={<Sparkles className="size-4" />}
                  title="Draft YAML policies"
                  active={state === 'generating'}
                  complete={state === 'ready'}
                />
              </div>
            </div>

            <div className="rounded-md border">
              <div className="border-b px-4 py-3">
                <p className="font-mono text-[10px] uppercase tracking-wider text-muted-foreground">
                  generated policy set
                </p>
              </div>
              <div className="divide-y">
                {previewPolicies.map((policy) => (
                  <div key={policy.id} className="grid gap-2 px-4 py-3">
                    <div className="flex items-center justify-between gap-3">
                      <span className="font-mono text-sm">{policy.id}</span>
                      <div className="flex gap-2">
                        {'action' in policy ? (
                          <Badge variant="outline" className="font-mono">
                            {policy.action}
                          </Badge>
                        ) : null}
                        <Badge variant="secondary" className="font-mono">
                          {policy.severity}
                        </Badge>
                      </div>
                    </div>
                    <p className="text-sm text-muted-foreground">
                      {'summary' in policy
                        ? policy.summary
                        : (policy.description ?? 'Generated guardrail')}
                    </p>
                  </div>
                ))}
              </div>
            </div>
          </div>
        </div>

        <DialogFooter>
          <Button type="button" variant="ghost" onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button type="button" onClick={runGenerate} disabled={!canGenerate || busy}>
            {busy ? <Loader2 className="animate-spin" /> : <Sparkles />}
            {state === 'ready' ? 'Create another version' : 'Save and generate guardrails'}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

function describeError(err: unknown): string {
  if (err instanceof Error) return err.message;
  return 'unknown error';
}

interface FieldProps {
  label: string;
  htmlFor: string;
  children: ReactNode;
}

function Field({ label, htmlFor, children }: FieldProps) {
  return (
    <div className="space-y-1.5">
      <Label
        htmlFor={htmlFor}
        className="font-mono text-[10px] uppercase tracking-wider text-muted-foreground"
      >
        {label}
      </Label>
      {children}
    </div>
  );
}

interface StepProps {
  icon: ReactNode;
  title: string;
  active: boolean;
  complete: boolean;
}

function Step({ icon, title, active, complete }: StepProps) {
  return (
    <div className="flex items-center gap-3 rounded-md border bg-background/50 px-3 py-2">
      <span className="flex size-8 items-center justify-center rounded-md border bg-muted">
        {active && !complete ? <Loader2 className="size-4 animate-spin" /> : icon}
      </span>
      <span className="min-w-0 flex-1 text-sm">{title}</span>
      <Badge variant={complete ? 'secondary' : 'outline'} className="font-mono">
        {complete ? 'done' : active ? 'running' : 'queued'}
      </Badge>
    </div>
  );
}
