import { useState, useEffect } from 'react';
import { ChevronRight, Play, Loader2, ShieldCheck } from 'lucide-react';
import { toast } from 'sonner';
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { api } from '@/api/client';
import { sessionEvents } from '@/hooks/sessionEvents';
import { cn } from '@/lib/utils';
import { FLOW_INFO } from './flowBlurbs';

type Band = 'small' | 'medium' | 'large';
type Category = 'Analysis' | 'Discovery' | 'Planning' | 'Authoring' | 'Review';

interface FlowMeta {
  name: string;
  label: string;
}

const CATEGORIES: Category[] = ['Analysis', 'Discovery', 'Planning', 'Authoring', 'Review'];

const FLOWS_BY_CATEGORY: Record<Category, FlowMeta[]> = {
  Analysis: [
    { name: 'research', label: 'Research' },
    { name: 'investigate', label: 'Investigate' },
    { name: 'architectural-analysis', label: 'Architectural Analysis' },
    { name: 'security-review', label: 'Security Review' },
    { name: 'gap-analysis', label: 'Gap Analysis' },
    { name: 'data-review', label: 'Data Review' },
    { name: 'devops-review', label: 'DevOps Review' },
    { name: 'issue-triage', label: 'Issue Triage' },
  ],
  Discovery: [
    { name: 'project-discovery', label: 'Project Discovery' },
    { name: 'project-documentation', label: 'Project Documentation' },
    { name: 'test-planning', label: 'Test Planning' },
  ],
  Planning: [
    { name: 'plan-a-feature', label: 'Plan a Feature' },
    { name: 'plan-implementation', label: 'Plan Implementation' },
    { name: 'plan-a-phased-build', label: 'Plan a Phased Build' },
    { name: 'plan-work-items', label: 'Plan Work Items' },
    { name: 'iterative-plan-review', label: 'Iterative Plan Review' },
  ],
  Authoring: [
    { name: 'adr', label: 'ADR' },
    { name: 'coding-standard', label: 'Coding Standard' },
    { name: 'runbook', label: 'Runbook' },
    { name: 'tdd', label: 'TDD' },
    { name: 'stakeholder-summary', label: 'Stakeholder Summary' },
  ],
  Review: [
    { name: 'code-review', label: 'Code Review' },
  ],
};

const BAND_LABELS: { value: Band; label: string }[] = [
  { value: 'small', label: 'Small' },
  { value: 'medium', label: 'Medium' },
  { value: 'large', label: 'Large' },
];

export function FlowLauncherDialog() {
  const [open, setOpen] = useState(false);
  const [projectId, setProjectId] = useState<string>('');
  const [placement, setPlacement] = useState<'new' | 'split'>('new');
  const [category, setCategory] = useState<Category>('Analysis');
  const [band, setBand] = useState<Band>('small');
  const [focus, setFocus] = useState('');
  const [fast, setFast] = useState(false);
  // Which flow row is expanded (one at a time) vs. which flow is mid-launch.
  // Expand (chevron) and launch (Run) are deliberately separate actions.
  const [expandedFlow, setExpandedFlow] = useState<string | null>(null);
  const [launchingFlow, setLaunchingFlow] = useState<string | null>(null);

  useEffect(() => {
    return sessionEvents.subscribe((ev) => {
      if (ev.type !== 'open_flow_launcher') return;
      setProjectId(ev.project_id);
      setPlacement(ev.placement ?? 'new');
      // Reset to defaults each time the dialog is opened.
      setCategory('Analysis');
      setBand('small');
      setFocus('');
      setFast(false);
      setExpandedFlow(null);
      setLaunchingFlow(null);
      setOpen(true);
    });
  }, []);

  function handleCategoryChange(cat: Category) {
    setCategory(cat);
    setExpandedFlow(null);
  }

  // Per-row launch. Behaviour is identical to the old bottom Launch button:
  // POST the run, then emit open_orchestrator_pane carrying the placement.
  async function handleRun(name: string) {
    if (!name || !projectId || launchingFlow) return;
    setLaunchingFlow(name);
    try {
      const { run_id } = await api.runs.launch({
        project_id: projectId,
        flow_name: name,
        band,
        input: { question: focus, ...(fast ? { concise: true } : {}) },
      });
      sessionEvents.emit({
        type: 'open_orchestrator_pane',
        state: { run_id, flow_name: name, band },
        placement,
      });
      setOpen(false);
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to launch flow');
    } finally {
      setLaunchingFlow(null);
    }
  }

  const flows = FLOWS_BY_CATEGORY[category];

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogContent
        className="flex flex-col gap-0 p-0 max-h-[85vh] sm:max-w-md grid-rows-[auto_minmax(0,1fr)_auto] overflow-hidden"
        showCloseButton={false}
      >
        <DialogHeader className="gap-2 px-4 pt-4 pb-3 border-b shrink-0">
          <DialogTitle className="text-sm font-medium">Launch a flow</DialogTitle>
          {/* Read-only assurance — flows never touch your code. */}
          <div className="inline-flex w-fit items-center gap-1.5 rounded-md bg-muted/60 px-2 py-1 text-xs text-muted-foreground">
            <ShieldCheck className="size-3.5 shrink-0 text-primary/70" />
            <span>Flows are read-only — they analyze and report, never modify your code.</span>
          </div>
        </DialogHeader>

        {/* Scrollable body */}
        <div className="flex flex-col gap-4 overflow-y-auto overscroll-contain px-4 py-3">
          {/* Run options — apply to whichever flow you Run below. */}
          <div className="flex flex-col gap-3">
            {/* Focus/question field */}
            <div className="flex flex-col gap-1.5">
              <Label htmlFor="flow-focus" className="text-xs text-muted-foreground">
                Focus / question
              </Label>
              <Input
                id="flow-focus"
                type="text"
                placeholder="What should the flow focus on?"
                value={focus}
                onChange={(e) => setFocus(e.target.value)}
              />
            </div>

            {/* Size selector */}
            <div className="flex flex-col gap-1.5">
              <Label className="text-xs text-muted-foreground">Size</Label>
              <div className="flex gap-1.5">
                {BAND_LABELS.map(({ value, label }) => (
                  <button
                    key={value}
                    type="button"
                    onClick={() => setBand(value)}
                    aria-pressed={band === value}
                    className={cn(
                      'flex-1 rounded-lg border py-1 text-xs transition-colors',
                      band === value
                        ? 'border-primary bg-primary/10 text-primary font-medium'
                        : 'border-border text-muted-foreground hover:bg-muted hover:text-foreground'
                    )}
                  >
                    {label}
                  </button>
                ))}
              </div>
            </div>

            {/* Fast mode toggle */}
            <div className="flex items-center justify-between">
              <div className="flex flex-col">
                <span className="text-xs font-medium text-foreground">Fast mode</span>
                <span className="text-xs text-muted-foreground">Fewer agents, quicker results</span>
              </div>
              <button
                type="button"
                role="switch"
                aria-checked={fast}
                onClick={() => setFast((v) => !v)}
                className={cn(
                  'relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
                  fast ? 'bg-primary' : 'bg-input'
                )}
              >
                <span
                  className={cn(
                    'pointer-events-none inline-block h-4 w-4 rounded-full bg-white shadow-lg transition-transform',
                    fast ? 'translate-x-4' : 'translate-x-0'
                  )}
                />
                <span className="sr-only">Fast mode</span>
              </button>
            </div>
          </div>

          <div className="border-t border-border/60" />

          {/* Flow picker */}
          <div className="flex flex-col gap-2">
            <span className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
              Choose a flow
            </span>

            {/* Category tabs — horizontal-scroll strip on mobile */}
            <div className="flex gap-1 overflow-x-auto no-scrollbar pb-0.5 shrink-0">
              {CATEGORIES.map((cat) => (
                <button
                  key={cat}
                  type="button"
                  onClick={() => handleCategoryChange(cat)}
                  className={cn(
                    'shrink-0 rounded-full border px-3 py-1 text-xs transition-colors whitespace-nowrap',
                    cat === category
                      ? 'border-primary bg-primary text-primary-foreground'
                      : 'border-border text-muted-foreground hover:bg-muted hover:text-foreground'
                  )}
                >
                  {cat}
                </button>
              ))}
            </div>

            {/* Flow list */}
            <div className="flex flex-col gap-1">
              {flows.map((flow) => {
                const info = FLOW_INFO[flow.name];
                const isExpanded = expandedFlow === flow.name;
                const isLaunching = launchingFlow === flow.name;
                const panelId = `flow-blurb-${flow.name}`;
                return (
                  <div
                    key={flow.name}
                    className={cn(
                      'rounded-lg border transition-colors',
                      isExpanded ? 'border-border bg-muted/40' : 'border-transparent hover:bg-muted/40'
                    )}
                  >
                    <div className="flex items-center gap-1.5 pr-2">
                      {/* Expand toggle — reveals the blurb; never launches. */}
                      <button
                        type="button"
                        onClick={() => setExpandedFlow(isExpanded ? null : flow.name)}
                        aria-expanded={isExpanded}
                        aria-controls={panelId}
                        aria-label={
                          isExpanded ? `Hide details for ${flow.label}` : `Show details for ${flow.label}`
                        }
                        className="flex min-w-0 flex-1 items-start gap-2 rounded-lg px-2.5 py-2 text-left max-md:min-h-[44px] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
                      >
                        <ChevronRight
                          className={cn(
                            'mt-0.5 size-4 shrink-0 text-muted-foreground transition-transform duration-200 motion-reduce:transition-none',
                            isExpanded && 'rotate-90'
                          )}
                        />
                        <span className="min-w-0 flex-1">
                          <span className="block text-sm font-medium text-foreground">{flow.label}</span>
                          <span className="block text-xs text-muted-foreground">
                            {info?.oneliner ?? ''}
                          </span>
                        </span>
                      </button>

                      {/* Run — the only launch action; clearly separate from expand. */}
                      <Button
                        type="button"
                        size="sm"
                        onClick={() => void handleRun(flow.name)}
                        disabled={launchingFlow !== null}
                        aria-label={`Run ${flow.label}`}
                        className="shrink-0 max-md:min-h-[44px]"
                      >
                        {isLaunching ? (
                          <Loader2 className="animate-spin" />
                        ) : (
                          <Play />
                        )}
                        Run
                      </Button>
                    </div>

                    {/* In-place blurb — grid-rows trick for a smooth, reduced-motion-safe expand. */}
                    <div
                      id={panelId}
                      role="region"
                      className={cn(
                        'grid transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none',
                        isExpanded ? 'grid-rows-[1fr]' : 'grid-rows-[0fr]'
                      )}
                    >
                      <div className="overflow-hidden">
                        <p className="px-2.5 pb-2.5 pl-9 text-xs leading-relaxed text-muted-foreground">
                          {info?.blurb ?? ''}
                        </p>
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>
          </div>
        </div>

        <DialogFooter className="shrink-0" showCloseButton />
      </DialogContent>
    </Dialog>
  );
}
