import { useState, useEffect } from 'react'
import { useMutation, useQueryClient } from '@tanstack/react-query'
import {
  Robot,
  Brain,
  Lightbulb,
  MagnifyingGlass,
  PencilSimple,
  Code,
  Chat,
  Gear,
  Shield,
  Rocket,
  CaretDown,
  CaretUp,
} from '@phosphor-icons/react'
import * as DialogPrimitive from '@radix-ui/react-dialog'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
import { ModelSelector } from '@/components/ui/model-selector'
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs'
import { useQuery } from '@tanstack/react-query'
import { useUiStore } from '@/store/ui'
import { createAgent, fetchProviders, isApiError } from '@/lib/api'
import type { Agent, AgentCreateRequest, AgentToolsCfg } from '@/lib/api'
import { AVATAR_COLORS } from '@/lib/constants'
import { ToolsAndPermissions } from './ToolsAndPermissions'

const ICON_OPTIONS = [
  { name: 'Robot', component: Robot },
  { name: 'Brain', component: Brain },
  { name: 'Lightbulb', component: Lightbulb },
  { name: 'MagnifyingGlass', component: MagnifyingGlass },
  { name: 'PencilSimple', component: PencilSimple },
  { name: 'Code', component: Code },
  { name: 'Chat', component: Chat },
  { name: 'Gear', component: Gear },
  { name: 'Shield', component: Shield },
  { name: 'Rocket', component: Rocket },
] as const

type IconName = typeof ICON_OPTIONS[number]['name']

function getIconComponent(name: IconName) {
  return ICON_OPTIONS.find((o) => o.name === name)?.component ?? Robot
}

// Fallback model list when no providers are connected

interface CreateAgentModalProps {
  /** Override modal open state (optional — defaults to Zustand store) */
  open?: boolean
  /** Override close handler (optional — defaults to Zustand store) */
  onClose?: () => void
  /** Override create handler (optional — defaults to REST API) */
  onCreate?: (data: AgentCreateRequest) => Promise<void>
}

export function CreateAgentModal({ open: openProp, onClose: onCloseProp, onCreate: onCreateProp }: CreateAgentModalProps) {
  const { createAgentModalOpen, closeCreateAgentModal } = useUiStore()
  const queryClient = useQueryClient()

  const isOpen = openProp !== undefined ? openProp : createAgentModalOpen
  const handleClose = onCloseProp ?? closeCreateAgentModal

  const { data: providersData, isError: providersError } = useQuery({
    queryKey: ['providers'],
    queryFn: fetchProviders,
    enabled: isOpen,
  })
  const providers = Array.isArray(providersData) ? providersData : []
  const connectedProviders = providers.filter((p) => p.status === 'connected')
  const availableModels = connectedProviders.flatMap((p) => p.models ?? [])
  const providerGroups = connectedProviders
    .filter((p) => (p.models ?? []).length > 0)
    .map((p) => ({ providerName: p.display_name ?? p.name ?? p.id, models: p.models ?? [] }))

  const [name, setName] = useState('')
  const [description, setDescription] = useState('')
  const [model, setModel] = useState('')
  const [color, setColor] = useState(AVATAR_COLORS[0])
  const [icon, setIcon] = useState<IconName>('Robot')
  const [temperature, setTemperature] = useState(1.0)
  const [advancedOpen, setAdvancedOpen] = useState(false)
  const [nameError, setNameError] = useState('')
  const [toolsState, setToolsState] = useState<AgentToolsCfg>({
    builtin: { default_policy: 'allow' },
  })

  const resetForm = () => {
    setName('')
    setDescription('')
    setModel('')
    setColor(AVATAR_COLORS[0])
    setIcon('Robot')
    setTemperature(1.0)
    setAdvancedOpen(false)
    setNameError('')
    setToolsState({ builtin: { default_policy: 'allow' } })
  }

  // Reset form state whenever the modal opens so stale values are not shown
  useEffect(() => {
    if (isOpen) {
      resetForm()
    }
    // resetForm references stable setState callbacks — isOpen is the only meaningful dep
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isOpen])

  const AvatarIcon = getIconComponent(icon)

  const { mutate: doCreate, isPending } = useMutation({
    mutationFn: async (data: AgentCreateRequest) => {
      if (onCreateProp) {
        await onCreateProp(data)
        return data as Agent
      }
      return createAgent(data)
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['agents'] })
      handleClose()
      resetForm()
    },
    onError: (err: Error) => {
      useUiStore.getState().addToast({ message: isApiError(err) ? err.userMessage : err instanceof Error ? err.message : 'Failed to create agent', variant: 'error' })
    },
  })

  const handleCreate = () => {
    if (!name.trim()) {
      setNameError('Name is required')
      return
    }
    doCreate({
      name: name.trim(),
      description: description || undefined,
      model: model || undefined,
      color,
      icon,
      model_params: { temperature },
      tools_cfg: toolsState,
    })
  }

  return (
    <DialogPrimitive.Root open={isOpen} onOpenChange={(open) => !open && handleClose()}>
      <DialogPrimitive.Portal>
        <DialogPrimitive.Overlay className="fixed inset-0 z-50 bg-black/60 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0" />
        <DialogPrimitive.Content className="fixed left-[50%] top-[50%] z-50 w-full sm:max-w-lg max-h-[calc(100vh-4rem)] translate-x-[-50%] translate-y-[-50%] border border-[var(--color-border)] bg-[var(--color-surface-1)] rounded-xl p-6 shadow-xl flex flex-col data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95">
          <DialogPrimitive.Title className="font-headline text-lg font-bold text-[var(--color-secondary)] mb-1">
            Create Agent
          </DialogPrimitive.Title>
          <DialogPrimitive.Description className="text-sm text-[var(--color-muted)] mb-5">
            Configure a new custom agent with a persona, model, and tools.
          </DialogPrimitive.Description>

          <Tabs defaultValue="general" className="flex-1 min-h-0 flex flex-col">
            <TabsList className="shrink-0 mb-3">
              <TabsTrigger value="general">General</TabsTrigger>
              <TabsTrigger value="tools">Tools &amp; Permissions</TabsTrigger>
            </TabsList>

            <TabsContent value="general" className="flex-1 overflow-y-auto min-h-0 mt-0">
              <div className="space-y-4 pr-1">
                {/* Avatar preview + color + icon */}
                <div>
                  <label className="text-xs font-medium text-[var(--color-muted)] mb-2 block">
                    Avatar
                  </label>
                  <div className="flex items-start gap-4">
                    <div
                      className="w-12 h-12 rounded-full flex items-center justify-center shrink-0"
                      style={{ backgroundColor: color }}
                    >
                      <AvatarIcon size={20} className="text-[var(--color-primary)]" />
                    </div>
                    <div className="flex-1 space-y-3">
                      <div>
                        <p className="text-[10px] text-[var(--color-muted)] mb-1.5">Color</p>
                        <div className="flex gap-2 flex-wrap">
                          {AVATAR_COLORS.map((c) => (
                            <button
                              key={c}
                              type="button"
                              onClick={() => setColor(c)}
                              className={`w-6 h-6 rounded-full transition-transform ${color === c ? 'ring-2 ring-[var(--color-secondary)] ring-offset-2 ring-offset-[var(--color-surface-1)] scale-110' : 'hover:scale-110'}`}
                              style={{ backgroundColor: c }}
                              aria-label={`Select color ${c}`}
                            />
                          ))}
                        </div>
                      </div>
                      <div>
                        <p className="text-[10px] text-[var(--color-muted)] mb-1.5">Icon</p>
                        <div className="grid grid-cols-5 gap-1.5">
                          {ICON_OPTIONS.map(({ name: iconName, component: IconComp }) => (
                            <button
                              key={iconName}
                              type="button"
                              onClick={() => setIcon(iconName)}
                              title={iconName}
                              className={`flex items-center justify-center w-8 h-8 rounded-md transition-colors ${
                                icon === iconName
                                  ? 'bg-[var(--color-accent)] text-[var(--color-primary)]'
                                  : 'bg-[var(--color-surface-2)] text-[var(--color-muted)] hover:text-[var(--color-secondary)]'
                              }`}
                            >
                              <IconComp size={16} />
                            </button>
                          ))}
                        </div>
                      </div>
                    </div>
                  </div>
                </div>

                {/* Name */}
                <div>
                  <label htmlFor="agent-name" className="text-xs font-medium text-[var(--color-muted)] mb-1.5 block">
                    Name <span className="text-[var(--color-error)]">*</span>
                  </label>
                  <Input
                    id="agent-name"
                    value={name}
                    onChange={(e) => {
                      setName(e.target.value)
                      if (e.target.value.trim()) setNameError('')
                    }}
                    placeholder="e.g. Research Assistant"
                    className={nameError ? 'border-[var(--color-error)]' : ''}
                    autoFocus
                  />
                  {nameError && (
                    <p className="mt-1 text-xs text-[var(--color-error)]">{nameError}</p>
                  )}
                </div>

                {/* Description */}
                <div>
                  <label htmlFor="agent-description" className="text-xs font-medium text-[var(--color-muted)] mb-1.5 block">
                    Description
                  </label>
                  <Textarea
                    id="agent-description"
                    value={description}
                    onChange={(e) => setDescription(e.target.value)}
                    placeholder="What does this agent do?"
                    rows={2}
                  />
                </div>

                {/* Model */}
                <div>
                  <label className="text-xs font-medium text-[var(--color-muted)] mb-1.5 block">
                    Model
                  </label>
                  {providersError && (
                    <div className="mb-2 rounded-md border border-[var(--color-error)]/40 bg-[var(--color-error)]/10 px-3 py-2">
                      <p className="text-xs text-[var(--color-error)] font-medium">Provider list unavailable</p>
                      <p className="text-xs text-[var(--color-error)]/80 mt-0.5">
                        Could not load connected providers. Verify your provider settings before creating this agent.
                      </p>
                    </div>
                  )}
                  <ModelSelector
                    models={availableModels}
                    value={model}
                    onChange={setModel}
                    placeholder="Use provider default"
                    providerGroups={providerGroups}
                  />
                </div>

                {/* Advanced model params */}
                <div className="rounded-md border border-[var(--color-border)] bg-[var(--color-surface-1)] overflow-hidden">
                  <button
                    type="button"
                    onClick={() => setAdvancedOpen((o) => !o)}
                    className="flex items-center justify-between w-full px-3 py-2.5 text-sm font-medium text-[var(--color-secondary)] hover:text-[var(--color-accent)] transition-colors"
                  >
                    <span>Advanced</span>
                    {advancedOpen ? <CaretUp size={13} /> : <CaretDown size={13} />}
                  </button>
                  {advancedOpen && (
                    <div className="px-3 pb-3 border-t border-[var(--color-border)] pt-3 space-y-1">
                      <div className="flex items-center justify-between">
                        <span className="text-xs text-[var(--color-muted)]">Temperature</span>
                        <span className="text-xs font-mono text-[var(--color-secondary)]">{temperature.toFixed(2)}</span>
                      </div>
                      <input
                        type="range"
                        min={0}
                        max={2}
                        step={0.05}
                        value={temperature}
                        onChange={(e) => setTemperature(Number(e.target.value))}
                        className="w-full h-1.5 rounded-full appearance-none cursor-pointer"
                        style={{
                          background: `linear-gradient(to right, var(--color-accent) 0%, var(--color-accent) ${(temperature / 2) * 100}%, var(--color-border) ${(temperature / 2) * 100}%, var(--color-border) 100%)`,
                        }}
                      />
                    </div>
                  )}
                </div>
              </div>
            </TabsContent>

            <TabsContent value="tools" className="flex-1 overflow-y-auto min-h-0 mt-0 pr-1">
              <ToolsAndPermissions
                agentId={null}
                agentType="custom"
                tools={toolsState}
                onChange={setToolsState}
              />
            </TabsContent>
          </Tabs>

          {/* Actions */}
          <div className="flex justify-end gap-2 mt-6">
            <Button
              variant="outline"
              onClick={() => { handleClose(); resetForm() }}
              disabled={isPending}
            >
              Cancel
            </Button>
            <Button onClick={handleCreate} disabled={isPending}>
              {isPending ? 'Creating...' : 'Create Agent'}
            </Button>
          </div>
        </DialogPrimitive.Content>
      </DialogPrimitive.Portal>
    </DialogPrimitive.Root>
  )
}
