/**
 * AgentTypeForm Component
 *
 * React Hook Form-based form for creating and editing agent types.
 * Features tabbed interface for organizing form sections.
 */

'use client';

import { useEffect, useState } from 'react';
import { useForm, Controller } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import { Label } from '@/components/ui/label';
import { Checkbox } from '@/components/ui/checkbox';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { Badge } from '@/components/ui/badge';
import { Separator } from '@/components/ui/separator';
import { FileText, Cpu, Shield, MessageSquare, Sliders, Save, ArrowLeft, X } from 'lucide-react';
import {
  agentTypeCreateSchema,
  type AgentTypeCreateFormValues,
  AVAILABLE_MODELS,
  AVAILABLE_MCP_SERVERS,
  defaultAgentTypeValues,
  generateSlug,
} from '@/lib/validations/agentType';
import type { AgentTypeResponse } from '@/lib/api/types/agentTypes';

interface AgentTypeFormProps {
  agentType?: AgentTypeResponse;
  onSubmit: (data: AgentTypeCreateFormValues) => void;
  onCancel: () => void;
  isSubmitting?: boolean;
  className?: string;
}

export function AgentTypeForm({
  agentType,
  onSubmit,
  onCancel,
  isSubmitting = false,
  className,
}: AgentTypeFormProps) {
  const isEditing = !!agentType;
  const [activeTab, setActiveTab] = useState('basic');
  const [expertiseInput, setExpertiseInput] = useState('');

  // Always use create schema for validation - editing requires all fields too
  const form = useForm<AgentTypeCreateFormValues>({
    resolver: zodResolver(agentTypeCreateSchema),
    defaultValues: agentType
      ? {
          name: agentType.name,
          slug: agentType.slug,
          description: agentType.description,
          expertise: agentType.expertise,
          personality_prompt: agentType.personality_prompt,
          primary_model: agentType.primary_model,
          fallback_models: agentType.fallback_models,
          model_params: (agentType.model_params ?? {
            temperature: 0.7,
            max_tokens: 8192,
            top_p: 0.95,
          }) as AgentTypeCreateFormValues['model_params'],
          mcp_servers: agentType.mcp_servers,
          tool_permissions: agentType.tool_permissions,
          is_active: agentType.is_active,
        }
      : defaultAgentTypeValues,
  });

  const {
    register,
    control,
    handleSubmit,
    watch,
    setValue,
    formState: { errors },
  } = form;

  const watchName = watch('name');
  /* istanbul ignore next -- defensive fallback, expertise always has default */
  const watchExpertise = watch('expertise') || [];
  /* istanbul ignore next -- defensive fallback, mcp_servers always has default */
  const watchMcpServers = watch('mcp_servers') || [];

  // Auto-generate slug from name for new agent types
  useEffect(() => {
    if (!isEditing && watchName) {
      const slug = generateSlug(watchName);
      setValue('slug', slug, { shouldValidate: true });
    }
  }, [watchName, isEditing, setValue]);

  const handleAddExpertise = () => {
    if (expertiseInput.trim()) {
      const newExpertise = expertiseInput.trim().toLowerCase();
      if (!watchExpertise.includes(newExpertise)) {
        setValue('expertise', [...watchExpertise, newExpertise]);
      }
      setExpertiseInput('');
    }
  };

  const handleRemoveExpertise = (skill: string) => {
    setValue(
      'expertise',
      watchExpertise.filter((e) => e !== skill)
    );
  };

  /* istanbul ignore next -- Radix UI checkbox handlers can't be tested in JSDOM */
  const handleMcpServerToggle = (serverId: string, checked: boolean) => {
    if (checked) {
      setValue('mcp_servers', [...watchMcpServers, serverId]);
    } else {
      setValue(
        'mcp_servers',
        watchMcpServers.filter((s) => s !== serverId)
      );
    }
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)} className={className}>
      {/* Header */}
      <div className="mb-6 flex items-center gap-4">
        <Button type="button" variant="ghost" size="icon" onClick={onCancel}>
          <ArrowLeft className="h-4 w-4" />
          <span className="sr-only">Go back</span>
        </Button>
        <div className="flex-1">
          <h1 className="text-3xl font-bold">
            {isEditing ? 'Edit Agent Type' : 'Create Agent Type'}
          </h1>
          <p className="text-muted-foreground">
            {isEditing ? 'Modify agent type configuration' : 'Define a new agent type template'}
          </p>
        </div>
        <div className="flex gap-2">
          <Button type="button" variant="outline" onClick={onCancel} disabled={isSubmitting}>
            Cancel
          </Button>
          <Button type="submit" disabled={isSubmitting}>
            <Save className="mr-2 h-4 w-4" />
            {isSubmitting ? 'Saving...' : isEditing ? 'Save Changes' : 'Create'}
          </Button>
        </div>
      </div>

      {/* Tabbed Form */}
      <Tabs value={activeTab} onValueChange={setActiveTab}>
        <TabsList className="grid w-full grid-cols-4">
          <TabsTrigger value="basic">
            <FileText className="mr-2 h-4 w-4" />
            Basic Info
          </TabsTrigger>
          <TabsTrigger value="model">
            <Cpu className="mr-2 h-4 w-4" />
            Model
          </TabsTrigger>
          <TabsTrigger value="permissions">
            <Shield className="mr-2 h-4 w-4" />
            Permissions
          </TabsTrigger>
          <TabsTrigger value="personality">
            <MessageSquare className="mr-2 h-4 w-4" />
            Personality
          </TabsTrigger>
        </TabsList>

        {/* Basic Info Tab */}
        <TabsContent value="basic" className="space-y-6">
          <Card>
            <CardHeader>
              <CardTitle>Basic Information</CardTitle>
              <CardDescription>
                Define the agent type name, description, and expertise areas
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-6">
              <div className="grid gap-4 md:grid-cols-2">
                <div className="space-y-2">
                  <Label htmlFor="name">
                    Name <span className="text-destructive">*</span>
                  </Label>
                  <Input
                    id="name"
                    placeholder="e.g., Software Architect"
                    {...register('name')}
                    aria-invalid={!!errors.name}
                    aria-describedby={errors.name ? 'name-error' : undefined}
                  />
                  {errors.name && (
                    <p id="name-error" className="text-sm text-destructive" role="alert">
                      {errors.name.message}
                    </p>
                  )}
                </div>
                <div className="space-y-2">
                  <Label htmlFor="slug">
                    Slug <span className="text-destructive">*</span>
                  </Label>
                  <Input
                    id="slug"
                    placeholder="e.g., software-architect"
                    {...register('slug')}
                    aria-invalid={!!errors.slug}
                    aria-describedby={errors.slug ? 'slug-error' : undefined}
                  />
                  {errors.slug && (
                    <p id="slug-error" className="text-sm text-destructive" role="alert">
                      {errors.slug.message}
                    </p>
                  )}
                  <p className="text-xs text-muted-foreground">
                    URL-friendly identifier (auto-generated from name)
                  </p>
                </div>
              </div>

              <div className="grid gap-4 md:grid-cols-2">
                <div className="space-y-2">
                  <Label htmlFor="status">Status</Label>
                  <Controller
                    name="is_active"
                    control={control}
                    render={({ field }) => (
                      <Select
                        value={field.value ? 'active' : 'inactive'}
                        onValueChange={
                          /* istanbul ignore next -- Radix Select handlers can't be tested in JSDOM */
                          (val) => field.onChange(val === 'active')
                        }
                      >
                        <SelectTrigger id="status">
                          <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                          <SelectItem value="active">Active</SelectItem>
                          <SelectItem value="inactive">Inactive / Draft</SelectItem>
                        </SelectContent>
                      </Select>
                    )}
                  />
                </div>
              </div>

              <div className="space-y-2">
                <Label htmlFor="description">Description</Label>
                <Textarea
                  id="description"
                  placeholder="Describe what this agent type does..."
                  rows={3}
                  {...register('description')}
                  aria-invalid={!!errors.description}
                  aria-describedby={errors.description ? 'description-error' : undefined}
                />
                {errors.description && (
                  <p id="description-error" className="text-sm text-destructive" role="alert">
                    {errors.description.message}
                  </p>
                )}
              </div>

              <div className="space-y-2">
                <Label>Expertise Areas</Label>
                <p className="text-sm text-muted-foreground">Add skills and areas of expertise</p>
                <div className="flex gap-2">
                  <Input
                    placeholder="e.g., System Design"
                    value={expertiseInput}
                    onChange={(e) => setExpertiseInput(e.target.value)}
                    onKeyDown={(e) => {
                      if (e.key === 'Enter') {
                        e.preventDefault();
                        handleAddExpertise();
                      }
                    }}
                  />
                  <Button type="button" variant="outline" onClick={handleAddExpertise}>
                    Add
                  </Button>
                </div>
                <div className="flex flex-wrap gap-2 pt-2">
                  {watchExpertise.map((skill) => (
                    <Badge key={skill} variant="secondary" className="gap-1">
                      {skill}
                      <button
                        type="button"
                        className="ml-1 rounded-full hover:bg-muted"
                        onClick={() => handleRemoveExpertise(skill)}
                        aria-label={`Remove ${skill}`}
                      >
                        <X className="h-3 w-3" />
                      </button>
                    </Badge>
                  ))}
                </div>
              </div>
            </CardContent>
          </Card>
        </TabsContent>

        {/* Model Configuration Tab */}
        <TabsContent value="model" className="space-y-6">
          <Card>
            <CardHeader>
              <CardTitle>Model Selection</CardTitle>
              <CardDescription>Choose the AI models that power this agent type</CardDescription>
            </CardHeader>
            <CardContent className="space-y-6">
              <div className="grid gap-4 md:grid-cols-2">
                <div className="space-y-2">
                  <Label htmlFor="primary_model">
                    Primary Model <span className="text-destructive">*</span>
                  </Label>
                  <Controller
                    name="primary_model"
                    control={control}
                    render={({ field }) => (
                      <Select value={field.value} onValueChange={field.onChange}>
                        <SelectTrigger id="primary_model">
                          <SelectValue placeholder="Select model" />
                        </SelectTrigger>
                        <SelectContent>
                          {AVAILABLE_MODELS.map((model) => (
                            <SelectItem key={model.value} value={model.value}>
                              {model.label}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    )}
                  />
                  {errors.primary_model && (
                    <p className="text-sm text-destructive" role="alert">
                      {errors.primary_model.message}
                    </p>
                  )}
                  <p className="text-xs text-muted-foreground">Main model used for this agent</p>
                </div>
                <div className="space-y-2">
                  <Label htmlFor="fallback_model">Fallover Model</Label>
                  <Controller
                    name="fallback_models"
                    control={control}
                    render={({ field }) => (
                      <Select
                        value={field.value?.[0] || ''}
                        onValueChange={
                          /* istanbul ignore next -- Radix Select handlers can't be tested in JSDOM */
                          (val) => field.onChange([val])
                        }
                      >
                        <SelectTrigger id="fallback_model">
                          <SelectValue placeholder="Select model" />
                        </SelectTrigger>
                        <SelectContent>
                          {AVAILABLE_MODELS.map((model) => (
                            <SelectItem key={model.value} value={model.value}>
                              {model.label}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    )}
                  />
                  <p className="text-xs text-muted-foreground">
                    Backup model if primary is unavailable
                  </p>
                </div>
              </div>
            </CardContent>
          </Card>

          <Card>
            <CardHeader>
              <CardTitle className="flex items-center gap-2">
                <Sliders className="h-5 w-5" />
                Model Parameters
              </CardTitle>
              <CardDescription>Fine-tune the model behavior</CardDescription>
            </CardHeader>
            <CardContent className="space-y-6">
              <div className="grid gap-6 md:grid-cols-3">
                <div className="space-y-2">
                  <Label htmlFor="temperature">Temperature</Label>
                  <Controller
                    name="model_params.temperature"
                    control={control}
                    render={({ field }) => (
                      <Input
                        id="temperature"
                        type="number"
                        step="0.1"
                        min="0"
                        max="2"
                        value={field.value ?? 0.7}
                        onChange={(e) => field.onChange(parseFloat(e.target.value))}
                      />
                    )}
                  />
                  <p className="text-xs text-muted-foreground">0 = deterministic, 2 = creative</p>
                </div>
                <div className="space-y-2">
                  <Label htmlFor="max_tokens">Max Tokens</Label>
                  <Controller
                    name="model_params.max_tokens"
                    control={control}
                    render={({ field }) => (
                      <Input
                        id="max_tokens"
                        type="number"
                        step="1024"
                        min="1024"
                        max="128000"
                        value={field.value ?? 8192}
                        onChange={(e) => field.onChange(parseInt(e.target.value, 10))}
                      />
                    )}
                  />
                  <p className="text-xs text-muted-foreground">Maximum response length</p>
                </div>
                <div className="space-y-2">
                  <Label htmlFor="top_p">Top P</Label>
                  <Controller
                    name="model_params.top_p"
                    control={control}
                    render={({ field }) => (
                      <Input
                        id="top_p"
                        type="number"
                        step="0.05"
                        min="0"
                        max="1"
                        value={field.value ?? 0.95}
                        onChange={(e) => field.onChange(parseFloat(e.target.value))}
                      />
                    )}
                  />
                  <p className="text-xs text-muted-foreground">Nucleus sampling threshold</p>
                </div>
              </div>
            </CardContent>
          </Card>
        </TabsContent>

        {/* MCP Permissions Tab */}
        <TabsContent value="permissions" className="space-y-6">
          <Card>
            <CardHeader>
              <CardTitle>MCP Server Permissions</CardTitle>
              <CardDescription>Configure which MCP servers this agent can access</CardDescription>
            </CardHeader>
            <CardContent className="space-y-4">
              {AVAILABLE_MCP_SERVERS.map((server) => (
                <div key={server.id} className="rounded-lg border p-4">
                  <div className="flex items-center justify-between">
                    <div className="flex items-center gap-3">
                      <Checkbox
                        id={`mcp-${server.id}`}
                        checked={watchMcpServers.includes(server.id)}
                        onCheckedChange={
                          /* istanbul ignore next -- Radix Checkbox handlers can't be tested in JSDOM */
                          (checked) => handleMcpServerToggle(server.id, checked === true)
                        }
                      />
                      <div>
                        <Label htmlFor={`mcp-${server.id}`} className="font-medium">
                          {server.name}
                        </Label>
                        <p className="text-sm text-muted-foreground">{server.description}</p>
                      </div>
                    </div>
                  </div>
                </div>
              ))}
            </CardContent>
          </Card>
        </TabsContent>

        {/* Personality Prompt Tab */}
        <TabsContent value="personality" className="space-y-6">
          <Card>
            <CardHeader>
              <CardTitle>Personality Prompt</CardTitle>
              <CardDescription>
                Define the agent&apos;s personality, behavior, and communication style. This prompt
                shapes how the agent approaches tasks and interacts.
              </CardDescription>
            </CardHeader>
            <CardContent>
              <div className="space-y-4">
                <Textarea
                  id="personality_prompt"
                  placeholder="You are a..."
                  rows={15}
                  className="font-mono text-sm"
                  {...register('personality_prompt')}
                  aria-invalid={!!errors.personality_prompt}
                  aria-describedby={
                    errors.personality_prompt ? 'personality_prompt-error' : undefined
                  }
                />
                {errors.personality_prompt && (
                  <p
                    id="personality_prompt-error"
                    className="text-sm text-destructive"
                    role="alert"
                  >
                    {errors.personality_prompt.message}
                  </p>
                )}
                <div className="flex items-center gap-4 text-sm text-muted-foreground">
                  <span>Character count: {watch('personality_prompt')?.length || 0}</span>
                  <Separator orientation="vertical" className="h-4" />
                  <span className="text-xs">
                    Tip: Be specific about expertise, communication style, and decision-making
                    approach
                  </span>
                </div>
              </div>
            </CardContent>
          </Card>
        </TabsContent>
      </Tabs>
    </form>
  );
}
