import { useState } from 'react';
import { Bot, FolderOpen, X, Sparkles } from 'lucide-react';
import { trpc } from '@/lib/trpc';
import { useNotify } from '@/hooks/useNotify';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Card, CardContent } from '@/components/ui/card';
import { cn } from '@/lib/utils';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  Dialog,
  DialogContent,
} from '@/components/ui/dialog';
import type { AgentCatalogItem } from '../../../../shared/api-types';
import { DATA_TYPE_CONFIG, SCHEDULE_OPTIONS } from './types';
import { TemplateSelectCard } from './TemplateSelectCard';
import { PromptBuilderChat } from './PromptBuilderChat';

export function InlineAgentCreationStepper({
  catalog,
  isLoadingCatalog,
  onCancel,
  onCreated,
}: {
  catalog: AgentCatalogItem[];
  isLoadingCatalog: boolean;
  onCancel: () => void;
  onCreated: () => void;
}) {
  const createLocalMutation = trpc.agent.local.create.useMutation();
  const createCloudMutation = trpc.agent.cloud.create.useMutation();
  const { notify, notifyError } = useNotify();

  const [step, setStep] = useState<1 | 2 | 3>(1);
  const [selectedTemplate, setSelectedTemplate] = useState<AgentCatalogItem | null>(null);
  const [name, setName] = useState('');
  const [directory, setDirectory] = useState('');
  const [promptDialogOpen, setPromptDialogOpen] = useState(false);
  const [dataTypes, setDataTypes] = useState<string[]>([]);
  const [schedule, setSchedule] = useState('0 * * * *');
  const [promptTemplate, setPromptTemplate] = useState('');
  const [agentConfig, setAgentConfig] = useState<Record<string, unknown> | null>(null);
  const [error, setError] = useState('');

  const isSubmitting = createLocalMutation.isPending || createCloudMutation.isPending;

  function applyTemplateDefaults(item: AgentCatalogItem) {
    setSelectedTemplate(item);
    setName(item.name);
    setDirectory('');
    setDataTypes((item.supportedDataTypes ?? []).slice(0, 2));
    setSchedule('0 * * * *');
    setPromptTemplate('');
    setAgentConfig(null);
    setError('');
    setStep(2);
  }

  async function pickDirectory() {
    try {
      const result = await window.electronDialog.showOpenDialog({
        properties: ['openDirectory'],
        title: 'Select directory for agent to watch',
      });
      if (!result.canceled && result.filePaths.length > 0) {
        setDirectory(result.filePaths[0]!);
      }
    } catch {
      // noop
    }
  }

  function toggleDataType(type: string) {
    setDataTypes(prev =>
      prev.includes(type) ? prev.filter(t => t !== type) : [...prev, type],
    );
  }

  function nextFromConfig() {
    if (!selectedTemplate) return;
    if (!name.trim()) {
      setError('Agent name is required.');
      return;
    }
    if (selectedTemplate.type === 'local_directory' && !directory) {
      setError('Select a directory.');
      return;
    }
    if (dataTypes.length === 0) {
      setError('Select at least one data type.');
      return;
    }
    setError('');
    setStep(3);
  }

  function handleCreate() {
    if (!selectedTemplate) return;

    setError('');

    if (selectedTemplate.type === 'local_directory') {
      createLocalMutation.mutate(
        {
          name,
          directory,
          dataTypes,
          scheduleCron: schedule,
          agentConfig: agentConfig ?? null,
        },
        {
          onSuccess: () => {
            notify('success', 'toast.agent.created');
            onCreated();
          },
          onError: (err) => {
            notifyError('toast.agent.createError', err);
            setError(err.message);
          },
        },
      );
      return;
    }

    createCloudMutation.mutate(
      {
        name,
        provider: selectedTemplate.provider as 'gmail' | 'teams' | 'outlook',
        dataTypes,
        scheduleCron: schedule,
        promptTemplate,
        filterConfig: {},
      },
      {
        onSuccess: () => {
          notify('success', 'toast.agent.created');
          onCreated();
        },
        onError: (err) => {
          notifyError('toast.agent.createError', err);
          setError(err.message);
        },
      },
    );
  }

  return (
    <div className="flex flex-col gap-5 w-full">

      {step === 1 && (
        <div className="flex flex-col gap-5">
          <div className="pb-1">
            <p className="text-xs font-semibold uppercase tracking-widest text-muted-foreground/60 mb-2">Step 1 of 3</p>
            <h2 className="text-3xl font-semibold tracking-tight leading-tight">
              Choose your<br />
              <span className="text-muted-foreground/50">starting template.</span>
            </h2>
            <p className="text-sm text-muted-foreground mt-3 leading-relaxed">Pick a starting point — you can customize everything before the agent goes live.</p>
          </div>

          {isLoadingCatalog && (
            <div className="rounded-lg border border-dashed px-4 py-10 text-sm text-muted-foreground text-center bg-muted/20">
              Loading templates...
            </div>
          )}

          {!isLoadingCatalog && catalog.length === 0 && (
            <div className="rounded-xl border border-dashed px-6 py-10 text-center">
              <Bot className="size-8 mx-auto mb-3 text-muted-foreground/50" />
              <p className="text-sm text-muted-foreground">No templates available yet. Add your server URL in Account settings, then try again.</p>
            </div>
          )}

          <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
            {catalog.map((item) => (
              <TemplateSelectCard
                key={item.id}
                item={item}
                selected={selectedTemplate?.id === item.id}
                onSelect={() => applyTemplateDefaults(item)}
              />
            ))}
          </div>
        </div>
      )}

      {step === 2 && selectedTemplate && (
        <div className="flex flex-col gap-7">
          <div className="pb-1">
            <p className="text-xs font-semibold uppercase tracking-widest text-muted-foreground/60 mb-2">Step 2 of 3</p>
            <h2 className="text-3xl font-semibold tracking-tight leading-tight">
              Configure<br />
              <input
                value={name}
                onChange={(e) => setName(e.target.value)}
                className="text-muted-foreground/50 bg-transparent outline-none border-none w-full placeholder:text-muted-foreground/30 caret-primary"
                placeholder="agent name."
                spellCheck={false}
              />
            </h2>
            <p className="text-sm text-muted-foreground mt-3 leading-relaxed">
              {selectedTemplate.type === 'local_directory'
                ? 'Point it at your files, pick what to extract, and set the run schedule.'
                : 'Pick what to extract and set the run schedule.'}
            </p>
          </div>

          {/* Local directory: path picker */}
          {selectedTemplate.type === 'local_directory' && (
            <div>
              <label className="text-xs font-semibold uppercase tracking-widest text-muted-foreground/60 block mb-2">Directory</label>
              {directory && (
                <div className="flex items-center gap-2 bg-muted/40 rounded-lg px-3 py-2 text-xs font-mono mb-2">
                  <FolderOpen className="size-3 text-muted-foreground shrink-0" />
                  <span className="flex-1 truncate">{directory}</span>
                  <button onClick={() => setDirectory('')} className="text-muted-foreground hover:text-foreground transition-colors">
                    <X className="size-3" />
                  </button>
                </div>
              )}
              <Button size="sm" variant="outline" onClick={pickDirectory}>
                <FolderOpen className="size-3.5 mr-1.5" />
                {directory ? 'Change directory' : 'Select directory'}
              </Button>
            </div>
          )}

          {/* Cloud: sign-in notice */}
          {selectedTemplate.type !== 'local_directory' && (
            <div className="rounded-xl border border-dashed px-4 py-3 text-sm text-muted-foreground">
              After creating this agent, you'll be asked to sign in to <span className="font-medium text-foreground capitalize">{selectedTemplate.provider}</span> and grant read access.
            </div>
          )}

          {/* What to extract */}
          <div>
            <label className="text-xs font-semibold uppercase tracking-widest text-muted-foreground/60 block mb-3">What to extract</label>
            <div className="flex flex-wrap gap-2">
              {DATA_TYPE_CONFIG.map(({ value, label, Icon }) => {
                const active = dataTypes.includes(value);
                return (
                  <button
                    key={value}
                    onClick={() => toggleDataType(value)}
                    className={cn(
                      'inline-flex items-center gap-2 px-3.5 py-2 rounded-xl border text-sm font-medium transition-all duration-150',
                      active
                        ? 'bg-foreground text-background border-foreground'
                        : 'bg-background text-muted-foreground border-border/60 hover:border-border hover:text-foreground',
                    )}
                  >
                    <Icon className="size-3.5" />
                    {label}
                  </button>
                );
              })}
            </div>
          </div>

          {/* Batch interval */}
          <div>
            <label className="text-xs font-semibold uppercase tracking-widest text-muted-foreground/60 block mb-2">Batch interval</label>
            <Select value={schedule} onValueChange={setSchedule}>
              <SelectTrigger className="w-full">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {SCHEDULE_OPTIONS.map(opt => (
                  <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          {/* Extraction prompt builder */}
          {(() => {
            const unlocked = (selectedTemplate.type !== 'local_directory' || !!directory) && dataTypes.length > 0;
            return (
              <div>
                <Button
                  variant={promptTemplate || agentConfig ? 'outline' : 'default'}
                  size="sm"
                  disabled={!unlocked}
                  onClick={() => setPromptDialogOpen(true)}
                >
                  <Sparkles className="size-3.5 mr-1.5" />
                  {promptTemplate || agentConfig ? 'Edit extraction prompt' : 'Build extraction prompt'}
                </Button>

                <Dialog open={promptDialogOpen} onOpenChange={setPromptDialogOpen}>
                  <DialogContent showCloseButton={false} className="w-[95vw] max-w-[1100px] h-[75vh] max-h-[780px] flex flex-col gap-0 p-0 overflow-hidden">
                    <div className="flex-1 min-h-0 overflow-hidden flex flex-col">
                      <PromptBuilderChat
                        autoStart
                        agentType={selectedTemplate.type === 'local_directory' ? 'local_directory' : selectedTemplate.provider as 'gmail' | 'teams' | 'outlook'}
                        dataTypes={dataTypes}
                        directory={selectedTemplate.type === 'local_directory' ? directory : undefined}
                        onPromptUpdate={(p) => setPromptTemplate(p)}
                        onConfigUpdate={(c) => setAgentConfig(c)}
                      />
                    </div>
                    <div className="flex justify-end gap-2 px-5 py-4 border-t shrink-0">
                      <Button variant="outline" size="sm" onClick={() => setPromptDialogOpen(false)}>
                        Close
                      </Button>
                      <Button size="sm" onClick={() => setPromptDialogOpen(false)}>
                        Confirm
                      </Button>
                    </div>
                  </DialogContent>
                </Dialog>
              </div>
            );
          })()}
        </div>
      )}

      {step === 3 && selectedTemplate && (
        <div className="flex flex-col gap-5">
          <div className="pb-1">
            <p className="text-xs font-semibold uppercase tracking-widest text-muted-foreground/60 mb-2">Step 3 of 3</p>
            <h2 className="text-3xl font-semibold tracking-tight leading-tight">
              Review and<br />
              <span className="text-muted-foreground/50">create your agent.</span>
            </h2>
            <p className="text-sm text-muted-foreground mt-3 leading-relaxed">Everything looks good? Hit create and your agent will start running on schedule.</p>
          </div>
        <Card className="rounded-xl gap-0 py-0 shadow-none border-border/70">
          <CardContent className="p-5 flex flex-col gap-4">
            <div className="space-y-1">
              <p className="text-xs text-muted-foreground">Template</p>
              <p className="text-sm font-medium">{selectedTemplate.name}</p>
            </div>
            <div className="border rounded-lg px-4 py-3 grid gap-2 text-sm bg-background">
              <p><span className="text-muted-foreground">Name:</span> {name}</p>
              <p><span className="text-muted-foreground">Type:</span> {selectedTemplate.type}</p>
              <p><span className="text-muted-foreground">Data types:</span> {dataTypes.join(', ') || 'None'}</p>
              <p><span className="text-muted-foreground">Schedule:</span> {SCHEDULE_OPTIONS.find(s => s.value === schedule)?.label ?? schedule}</p>
              {selectedTemplate.type === 'local_directory' && directory && (
                <p><span className="text-muted-foreground">Directory:</span> {directory}</p>
              )}
              {(selectedTemplate.type === 'local_directory' ? agentConfig : promptTemplate) && (
                <p><span className="text-muted-foreground">Extraction config:</span> Added</p>
              )}
            </div>
          </CardContent>
        </Card>
        </div>
      )}

      {error && <p className="text-xs text-destructive">{error}</p>}

      <div className="flex items-center justify-between pt-1">
        <Button
          variant="outline"
          size="sm"
          onClick={() => {
            setError('');
            if (step === 1) {
              onCancel();
            } else {
              setStep(prev => (prev - 1) as 1 | 2 | 3);
            }
          }}
        >
          {step === 1 ? 'Cancel' : 'Back'}
        </Button>

        {step === 2 && (
          <Button size="sm" onClick={nextFromConfig}>
            Next
          </Button>
        )}

        {step === 3 && (
          <Button size="sm" onClick={handleCreate} disabled={isSubmitting}>
            Create agent now
          </Button>
        )}
      </div>
    </div>
  );
}
