import { HelpCircle } from 'lucide-react';

import { useState } from 'react';

import { Head, router, useForm } from '@inertiajs/react';

import SiteNav from '@/Components/Navigation/SiteNav';
import { Button } from '@/Components/ui/button';
import { ConfirmDialog } from '@/Components/ui/confirm-dialog';
import { Input } from '@/Components/ui/input';
import { Label } from '@/Components/ui/label';
import { LoadingButton } from '@/Components/ui/loading-button';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/Components/ui/select';
import { Slider } from '@/Components/ui/slider';
import { Textarea } from '@/Components/ui/textarea';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/Components/ui/tooltip';
import { useUnsavedChanges } from '@/hooks/useUnsavedChanges';
import DashboardLayout from '@/Layouts/DashboardLayout';
import type { SiteBasic } from '@/types';

interface Settings {
  model: string | null;
  temperature: number | null;
  top_p: number | null;
  max_output_tokens: number | null;
  custom_instructions_enabled: boolean;
  custom_instructions: string | null;
}

interface Defaults {
  temperature_default: number;
  temperature_min: number;
  temperature_max: number;
  top_p_default: number;
  top_p_min: number;
  top_p_max: number;
  max_output_tokens_default: number;
  max_output_tokens_min: number;
  max_output_tokens_max: number;
}

interface Props {
  site: SiteBasic;
  settings: Settings | null;
  defaults: Defaults;
  allowedModels: string[];
}

function LabelWithTooltip({
  htmlFor,
  label,
  tooltip,
}: {
  htmlFor: string;
  label: string;
  tooltip: string;
}) {
  return (
    <div className="flex items-center gap-1">
      <Label htmlFor={htmlFor} className="text-sm font-medium">
        {label}
      </Label>
      <TooltipProvider>
        <Tooltip>
          <TooltipTrigger asChild>
            <HelpCircle className="h-3.5 w-3.5 text-muted-foreground cursor-help" />
          </TooltipTrigger>
          <TooltipContent side="right" className="max-w-xs">
            <p className="text-sm">{tooltip}</p>
          </TooltipContent>
        </Tooltip>
      </TooltipProvider>
    </div>
  );
}

export default function SiteAiSettings({ site, settings, defaults, allowedModels }: Props) {
  const [showReset, setShowReset] = useState(false);
  const { data, setData, put, processing, errors, isDirty } = useForm({
    model: settings?.model ?? 'gpt-4o-mini',
    temperature: settings?.temperature ?? defaults.temperature_default,
    top_p: settings?.top_p ?? defaults.top_p_default,
    max_output_tokens: settings?.max_output_tokens ?? defaults.max_output_tokens_default,
    custom_instructions_enabled: settings?.custom_instructions_enabled ?? false,
    custom_instructions: settings?.custom_instructions ?? '',
  });

  useUnsavedChanges(isDirty);

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    put(route('sites.settings.ai.update', site.id));
  };

  const handleReset = () => setShowReset(true);

  return (
    <>
      <Head title={`${site.name} - AI Settings`} />

      <div className="container py-6">
        <SiteNav
          siteId={site.id}
          canAnalyze
          canRecommend
          canCannibalization
          canOpportunityMap
          canGeographic
          canDevice
        />

        <h1 className="text-2xl font-bold tracking-tight">AI Settings</h1>
        <p className="text-muted-foreground mt-1">
          Configure AI generation settings for {site.name}.
        </p>

        <form onSubmit={handleSubmit} className="max-w-lg space-y-4 mt-6">
          <div>
            <LabelWithTooltip
              htmlFor="ai-model"
              label="Model"
              tooltip="The AI model used for content generation. More capable models may produce better results but cost more per token."
            />
            <Select value={data.model} onValueChange={(value) => setData('model', value)}>
              <SelectTrigger
                id="ai-model"
                className="mt-1"
                aria-invalid={!!errors.model}
                aria-describedby={errors.model ? 'ai-model-error' : undefined}
              >
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {allowedModels.map((m) => (
                  <SelectItem key={m} value={m}>
                    {m}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            {errors.model && (
              <p id="ai-model-error" className="text-sm text-destructive mt-1">
                {errors.model}
              </p>
            )}
          </div>

          <div>
            <LabelWithTooltip
              htmlFor="ai-temperature"
              label={`Temperature (${data.temperature})`}
              tooltip="Controls randomness. Lower values (0.0-0.3) produce focused, deterministic output. Higher values (0.7-2.0) produce more creative, varied output."
            />
            <Slider
              id="ai-temperature"
              min={defaults.temperature_min}
              max={defaults.temperature_max}
              step={0.1}
              value={[data.temperature]}
              onValueChange={([value]) => setData('temperature', value)}
              className="mt-2"
              aria-invalid={!!errors.temperature}
              aria-describedby={errors.temperature ? 'ai-temperature-error' : undefined}
            />
            {errors.temperature && (
              <p id="ai-temperature-error" className="text-sm text-destructive mt-1">
                {errors.temperature}
              </p>
            )}
          </div>

          <div>
            <LabelWithTooltip
              htmlFor="ai-top-p"
              label={`Top P (${data.top_p})`}
              tooltip="Controls diversity via nucleus sampling. 1.0 considers all tokens. Lower values (e.g. 0.1) only consider the most likely tokens."
            />
            <Slider
              id="ai-top-p"
              min={defaults.top_p_min}
              max={defaults.top_p_max}
              step={0.1}
              value={[data.top_p]}
              onValueChange={([value]) => setData('top_p', value)}
              className="mt-2"
              aria-invalid={!!errors.top_p}
              aria-describedby={errors.top_p ? 'ai-top-p-error' : undefined}
            />
            {errors.top_p && (
              <p id="ai-top-p-error" className="text-sm text-destructive mt-1">
                {errors.top_p}
              </p>
            )}
          </div>

          <div>
            <LabelWithTooltip
              htmlFor="ai-max-tokens"
              label="Max output tokens"
              tooltip="Maximum length of the generated content in tokens. One token is roughly 4 characters of English text."
            />
            <Input
              id="ai-max-tokens"
              type="number"
              min={defaults.max_output_tokens_min}
              max={defaults.max_output_tokens_max}
              value={data.max_output_tokens}
              onChange={(e) => setData('max_output_tokens', parseInt(e.target.value))}
              className="mt-1"
              aria-invalid={!!errors.max_output_tokens}
              aria-describedby={errors.max_output_tokens ? 'ai-max-tokens-error' : undefined}
            />
            {errors.max_output_tokens && (
              <p id="ai-max-tokens-error" className="text-sm text-destructive mt-1">
                {errors.max_output_tokens}
              </p>
            )}
          </div>

          <div className="flex items-center gap-2">
            <input
              type="checkbox"
              id="custom_instructions_enabled"
              checked={data.custom_instructions_enabled}
              onChange={(e) => setData('custom_instructions_enabled', e.target.checked)}
              className="rounded border-input"
            />
            <label htmlFor="custom_instructions_enabled" className="text-sm font-medium">
              Enable custom instructions
            </label>
          </div>

          {data.custom_instructions_enabled && (
            <div>
              <div className="flex items-center justify-between">
                <label htmlFor="ai-custom-instructions" className="text-sm font-medium">
                  Custom instructions
                </label>
                <span className="text-xs text-muted-foreground">
                  {data.custom_instructions.length} / 2000
                </span>
              </div>
              <Textarea
                id="ai-custom-instructions"
                value={data.custom_instructions}
                onChange={(e) => setData('custom_instructions', e.target.value)}
                rows={4}
                placeholder="Add custom instructions for AI content generation..."
                className="mt-1"
                aria-invalid={!!errors.custom_instructions}
                aria-describedby={
                  errors.custom_instructions ? 'ai-custom-instructions-error' : undefined
                }
                maxLength={2000}
              />
              {errors.custom_instructions && (
                <p id="ai-custom-instructions-error" className="text-sm text-destructive mt-1">
                  {errors.custom_instructions}
                </p>
              )}
            </div>
          )}

          <div className="flex gap-2 pt-2">
            <LoadingButton loading={processing}>Save Settings</LoadingButton>
            <Button type="button" variant="outline" onClick={handleReset}>
              Reset to Defaults
            </Button>
          </div>
        </form>
        <ConfirmDialog
          open={showReset}
          onOpenChange={setShowReset}
          title="Reset AI settings?"
          description="This will reset the AI model, temperature, and custom instructions to system defaults. Your existing drafts are not affected."
          confirmLabel="Reset to Defaults"
          variant="default"
          onConfirm={() => router.delete(route('sites.settings.ai.reset', site.id))}
        />
      </div>
    </>
  );
}

SiteAiSettings.layout = (page: React.ReactNode) => <DashboardLayout>{page}</DashboardLayout>;
