import { Link2, MessageSquare, X } from 'lucide-react';
import { toast } from 'sonner';

import { useState } from 'react';

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

import AdminPage from '@/Components/admin/AdminPage';
import { Button } from '@/Components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/Components/ui/card';
import { EmptyState } from '@/Components/ui/empty-state';
import { Input } from '@/Components/ui/input';
import { Label } from '@/Components/ui/label';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/Components/ui/select';
import { Textarea } from '@/Components/ui/textarea';
import { useMutationButton } from '@/hooks/useMutationButton';
import { useUnsavedChanges } from '@/hooks/useUnsavedChanges';
import AdminLayout from '@/Layouts/AdminLayout';

const ENTRY_TYPES = ['feature', 'improvement', 'fix', 'security'] as const;

interface FeedbackRow {
  id: number;
  category: string;
  message: string;
  user_name: string | null;
  status: string;
}

interface ChangelogEntryEditProps {
  entry: {
    id: number;
    title: string;
    body: string;
    version: string | null;
    type: string | null;
    published_at: string | null;
  };
  linked_feedback: FeedbackRow[];
  available_feedback: FeedbackRow[];
}

export default function ChangelogEntryEdit({
  entry,
  linked_feedback,
  available_feedback,
}: ChangelogEntryEditProps) {
  const { data, setData, patch, processing, errors, isDirty } = useForm({
    title: entry.title,
    body: entry.body,
    version: entry.version ?? '',
    type: entry.type ?? '',
    published_at: entry.published_at ?? '',
  });

  useUnsavedChanges(isDirty);

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    patch(route('admin.changelog-entries.update', entry.id));
  };

  const [selectedId, setSelectedId] = useState<string>('');

  const { processing: addingFeedback, onClick: handleAddFeedback } = useMutationButton(
    (opts) => {
      if (!selectedId) return;
      const ids = linked_feedback.map((f) => f.id).concat(Number(selectedId));
      router.post(
        route('admin.changelog-entries.link-feedback', entry.id),
        { feedback_ids: ids },
        {
          ...opts,
          preserveScroll: true,
          onSuccess: () => {
            setSelectedId('');
            toast.success('Feedback linked.');
            opts.onFinish?.();
          },
          onError: (errors) => {
            toast.error("Couldn't link that feedback. Retry.");
            opts.onError?.(errors);
          },
        },
      );
    },
  );

  const [removingFeedbackId, setRemovingFeedbackId] = useState<number | null>(null);
  const { processing: removingFeedback, onClick: triggerRemoveFeedback } = useMutationButton(
    (opts) => {
      if (removingFeedbackId === null) return;
      const ids = linked_feedback.filter((f) => f.id !== removingFeedbackId).map((f) => f.id);
      router.post(
        route('admin.changelog-entries.link-feedback', entry.id),
        { feedback_ids: ids },
        {
          ...opts,
          preserveScroll: true,
          onSuccess: () => {
            toast.success('Feedback unlinked.');
            opts.onFinish?.();
          },
          onError: (errors) => {
            toast.error("Couldn't unlink that feedback. Retry.");
            opts.onError?.(errors);
          },
        },
      );
    },
  );

  const handleRemoveFeedback = (id: number) => {
    setRemovingFeedbackId(id);
    triggerRemoveFeedback();
  };

  return (
    <AdminLayout>
      <AdminPage
        title="Edit Changelog Entry"
        subtitle={`Editing: ${entry.title}`}
        breadcrumbs={[
          { label: 'Admin', href: '/admin' },
          { label: 'Changelog', href: route('admin.changelog-entries.index') },
          { label: 'Edit' },
        ]}
      >
        <form onSubmit={handleSubmit} className="space-y-6">
          <Card>
            <CardHeader>
              <CardTitle>Entry Details</CardTitle>
            </CardHeader>
            <CardContent className="space-y-4">
              <div className="space-y-1">
                <Label htmlFor="title">Title *</Label>
                <Input
                  id="title"
                  value={data.title}
                  onChange={(e) => setData('title', e.target.value)}
                />
                {errors.title && <p className="text-sm text-destructive">{errors.title}</p>}
              </div>

              <div className="grid grid-cols-2 gap-4">
                <div className="space-y-1">
                  <Label htmlFor="version">Version</Label>
                  <Input
                    id="version"
                    value={data.version}
                    onChange={(e) => setData('version', e.target.value)}
                    placeholder="e.g. 2.4.0"
                  />
                  {errors.version && <p className="text-sm text-destructive">{errors.version}</p>}
                </div>

                <div className="space-y-1">
                  <Label htmlFor="type">Type</Label>
                  <Select value={data.type} onValueChange={(value) => setData('type', value)}>
                    <SelectTrigger id="type">
                      <SelectValue placeholder="Select type" />
                    </SelectTrigger>
                    <SelectContent>
                      {ENTRY_TYPES.map((t) => (
                        <SelectItem key={t} value={t}>
                          {t.charAt(0).toUpperCase() + t.slice(1)}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  {errors.type && <p className="text-sm text-destructive">{errors.type}</p>}
                </div>
              </div>

              <div className="space-y-1">
                <Label htmlFor="body">Body *</Label>
                <Textarea
                  id="body"
                  value={data.body}
                  onChange={(e) => setData('body', e.target.value)}
                  rows={10}
                />
                {errors.body && <p className="text-sm text-destructive">{errors.body}</p>}
              </div>

              <div className="space-y-1">
                <Label htmlFor="published_at">Publish Date (leave empty for draft)</Label>
                <Input
                  id="published_at"
                  type="datetime-local"
                  value={data.published_at}
                  onChange={(e) => setData('published_at', e.target.value)}
                />
                {errors.published_at && (
                  <p className="text-sm text-destructive">{errors.published_at}</p>
                )}
              </div>
            </CardContent>
          </Card>

          <div className="flex gap-3">
            <Button type="submit" disabled={processing}>
              {processing ? 'Saving…' : 'Save Changes'}
            </Button>
            <Button variant="outline" asChild>
              <Link href={route('admin.changelog-entries.index')}>Cancel</Link>
            </Button>
          </div>
        </form>

        {/* Linked Feedback — close-the-loop section */}
        <Card>
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <Link2 className="size-4" />
              Linked Feedback
            </CardTitle>
            <p className="text-sm text-muted-foreground">
              When this entry is published, linked feedback submitters will receive a "Your feedback
              shipped!" notification.
            </p>
          </CardHeader>
          <CardContent className="space-y-4">
            {linked_feedback.length > 0 ? (
              <ul className="space-y-2" aria-label="Linked feedback submissions">
                {linked_feedback.map((f) => (
                  <li
                    key={f.id}
                    className="flex items-start justify-between gap-2 rounded-md border px-3 py-2 text-sm"
                  >
                    <div className="min-w-0 flex-1">
                      <span className="font-medium capitalize">{f.category.replace('_', ' ')}</span>
                      {f.user_name && (
                        <span className="ml-2 text-muted-foreground">by {f.user_name}</span>
                      )}
                      <p className="mt-0.5 truncate text-muted-foreground">{f.message}</p>
                    </div>
                    <Button
                      variant="ghost"
                      size="icon"
                      className="size-6 shrink-0"
                      aria-label={`Remove feedback #${f.id}`}
                      onClick={() => handleRemoveFeedback(f.id)}
                      disabled={removingFeedback}
                    >
                      <X className="size-3" />
                    </Button>
                  </li>
                ))}
              </ul>
            ) : (
              <EmptyState
                size="sm"
                variant="zero"
                icon={MessageSquare}
                title="No feedback linked yet"
                description="Link feedback items to attribute this changelog entry to user requests."
              />
            )}

            {available_feedback.length > 0 && (
              <div className="flex gap-2">
                <Select value={selectedId} onValueChange={setSelectedId}>
                  <SelectTrigger className="flex-1" aria-label="Select feedback to link">
                    <SelectValue placeholder="Select feedback to link…" />
                  </SelectTrigger>
                  <SelectContent>
                    {available_feedback.map((f) => (
                      <SelectItem key={f.id} value={String(f.id)}>
                        #{f.id} · {f.category.replace('_', ' ')}
                        {f.user_name ? ` (${f.user_name})` : ''} — {f.message}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <Button
                  type="button"
                  variant="outline"
                  onClick={handleAddFeedback}
                  disabled={!selectedId || addingFeedback}
                >
                  Link
                </Button>
              </div>
            )}
          </CardContent>
        </Card>
      </AdminPage>
    </AdminLayout>
  );
}
