'use client';

import { useEffect, useMemo, useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { Pencil, Plus, Trash2 } from 'lucide-react';
import { toast } from 'sonner';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import { Spinner } from '@/components/ui/spinners';
import {
  createCategory,
  deleteCategory,
  fetchCategories,
  updateCategory,
} from '@/network/apis/dashboard/marketplace/marketplace.apis';
import { Category } from '@/network/apis/dashboard/marketplace/type';

type FormState = {
  name: string;
  slug: string;
  parent_id: string;
};

const EMPTY_FORM: FormState = { name: '', slug: '', parent_id: '' };

export function CategoriesManager() {
  const queryClient = useQueryClient();
  const { data: categories = [], isLoading } = useQuery({
    queryKey: ['marketplace-categories'],
    queryFn: fetchCategories,
  });

  const [editing, setEditing] = useState<Category | null>(null);
  const [creating, setCreating] = useState(false);
  const [deleting, setDeleting] = useState<Category | null>(null);
  const [form, setForm] = useState<FormState>(EMPTY_FORM);

  useEffect(() => {
    if (editing) {
      setForm({
        name: editing.name ?? '',
        slug: editing.slug ?? '',
        parent_id: editing.parent_id != null ? String(editing.parent_id) : '',
      });
    } else if (creating) {
      setForm(EMPTY_FORM);
    }
  }, [editing, creating]);

  const parentOptions = useMemo(
    () => categories.filter((c) => !editing || c.id !== editing.id),
    [categories, editing],
  );

  const nameById = useMemo(
    () => new Map(categories.map((c) => [c.id, c.name])),
    [categories],
  );

  const handleError = (e: unknown, fallback: string) => {
    const msg =
      (e as { response?: { data?: { message?: string } } })?.response?.data
        ?.message || fallback;
    toast.error(msg);
  };

  const closeDialogs = () => {
    setEditing(null);
    setCreating(false);
    setDeleting(null);
  };

  const invalidate = () =>
    queryClient.invalidateQueries({ queryKey: ['marketplace-categories'] });

  const createMutation = useMutation({
    mutationFn: () =>
      createCategory({
        name: form.name.trim(),
        slug: form.slug.trim() || undefined,
        parent_id: form.parent_id ? Number(form.parent_id) : null,
      }),
    onSuccess: () => {
      toast.success('Category created');
      invalidate();
      closeDialogs();
    },
    onError: (e) => handleError(e, 'Failed to create category'),
  });

  const updateMutation = useMutation({
    mutationFn: () =>
      updateCategory(editing!.id, {
        name: form.name.trim(),
        slug: form.slug.trim() || undefined,
        parent_id: form.parent_id ? Number(form.parent_id) : null,
      }),
    onSuccess: () => {
      toast.success('Category updated');
      invalidate();
      closeDialogs();
    },
    onError: (e) => handleError(e, 'Failed to update category'),
  });

  const deleteMutation = useMutation({
    mutationFn: (id: number) => deleteCategory(id),
    onSuccess: () => {
      toast.success('Category deleted');
      invalidate();
      closeDialogs();
    },
    onError: (e) => handleError(e, 'Failed to delete category'),
  });

  const formValid = form.name.trim().length > 0;
  const submitting = createMutation.isPending || updateMutation.isPending;

  return (
    <div className="space-y-5">
      <div className="flex justify-between items-center">
        <div>
          <h2 className="text-lg font-semibold">Categories</h2>
          <p className="text-sm text-muted-foreground">
            Organize the marketplace taxonomy used by offers.
          </p>
        </div>
        <Button onClick={() => setCreating(true)}>
          <Plus className="size-4 mr-1" /> New category
        </Button>
      </div>

      <Card>
        <CardContent className="p-0">
          {isLoading ? (
            <div className="flex items-center justify-center py-16">
              <Spinner className="size-8 animate-spin text-primary" />
            </div>
          ) : categories.length === 0 ? (
            <div className="py-16 text-center text-muted-foreground">
              No categories yet.
            </div>
          ) : (
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>#ID</TableHead>
                  <TableHead>Name</TableHead>
                  <TableHead>Slug</TableHead>
                  <TableHead>Parent</TableHead>
                  <TableHead>Offers</TableHead>
                  <TableHead className="text-right">Actions</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {categories.map((c) => (
                  <TableRow key={c.id}>
                    <TableCell className="font-mono text-sm">#{c.id}</TableCell>
                    <TableCell className="font-medium">{c.name}</TableCell>
                    <TableCell className="text-sm text-muted-foreground">
                      {c.slug ?? '—'}
                    </TableCell>
                    <TableCell className="text-sm">
                      {c.parent_id ? (nameById.get(c.parent_id) ?? `#${c.parent_id}`) : '—'}
                    </TableCell>
                    <TableCell className="text-sm">
                      {c.offers_count ?? 0}
                    </TableCell>
                    <TableCell className="text-right space-x-1">
                      <Button
                        size="sm"
                        variant="outline"
                        onClick={() => setEditing(c)}
                      >
                        <Pencil className="size-4" />
                      </Button>
                      <Button
                        size="sm"
                        variant="outline"
                        className="text-red-600 border-red-200"
                        onClick={() => setDeleting(c)}
                      >
                        <Trash2 className="size-4" />
                      </Button>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          )}
        </CardContent>
      </Card>

      {/* Create / Edit dialog */}
      <Dialog
        open={creating || !!editing}
        onOpenChange={(o) => !o && closeDialogs()}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>
              {editing ? `Edit category #${editing.id}` : 'New category'}
            </DialogTitle>
            <DialogDescription>
              Categories control how offers are filtered on the marketplace.
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-3">
            <div>
              <Label>
                Name <span className="text-red-500">*</span>
              </Label>
              <Input
                value={form.name}
                onChange={(e) => setForm({ ...form, name: e.target.value })}
                placeholder="e.g. Lifestyle"
              />
            </div>
            <div>
              <Label>Slug</Label>
              <Input
                value={form.slug}
                onChange={(e) => setForm({ ...form, slug: e.target.value })}
                placeholder="auto if empty"
              />
            </div>
            <div>
              <Label>Parent category</Label>
              <Select
                value={form.parent_id || 'none'}
                onValueChange={(v) =>
                  setForm({ ...form, parent_id: v === 'none' ? '' : v })
                }
              >
                <SelectTrigger>
                  <SelectValue placeholder="None (top-level)" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="none">None (top-level)</SelectItem>
                  {parentOptions.map((p) => (
                    <SelectItem key={p.id} value={String(p.id)}>
                      {p.name}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={closeDialogs}>
              Cancel
            </Button>
            <Button
              disabled={!formValid || submitting}
              onClick={() =>
                editing ? updateMutation.mutate() : createMutation.mutate()
              }
            >
              {submitting ? (
                <Spinner className="size-4 animate-spin mr-2" />
              ) : null}
              {editing ? 'Save changes' : 'Create'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Delete confirm */}
      <Dialog
        open={!!deleting}
        onOpenChange={(o) => !o && setDeleting(null)}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Delete category #{deleting?.id}?</DialogTitle>
            <DialogDescription>
              {deleting?.offers_count
                ? `This category is used by ${deleting.offers_count} offer(s).`
                : 'This action cannot be undone.'}
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDeleting(null)}>
              Cancel
            </Button>
            <Button
              variant="outline"
              className="text-red-600 border-red-300"
              disabled={deleteMutation.isPending}
              onClick={() => deleting && deleteMutation.mutate(deleting.id)}
            >
              {deleteMutation.isPending ? (
                <Spinner className="size-4 animate-spin mr-2" />
              ) : null}
              Delete
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
