import { useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import { Edit3, Hash, Plus, Trash2 } from 'lucide-react';
import {
    AlertDialog,
    AlertDialogAction,
    AlertDialogCancel,
    AlertDialogContent,
    AlertDialogDescription,
    AlertDialogFooter,
    AlertDialogHeader,
    AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Spinner } from '@/components/ui/spinner';
import { Textarea } from '@/components/ui/textarea';
import { projectLabels, projectCreateLabel, projectDeleteLabel, projectUpdateLabel } from '@/client';
import { useProject } from '@/contexts';
import {getApiErrorMessage} from '@/lib/api-error';

export function SettingsLabels() {
    const { project } = useProject();
    const queryClient = useQueryClient();

    const [editingId, setEditingId] = useState<number | null>(null);
    const [deletingId, setDeletingId] = useState<number | null>(null);
    const [showForm, setShowForm] = useState(false);
    const [name, setName] = useState('');
    const [color, setColor] = useState('#3b82f6');
    const [desc, setDesc] = useState('');

    const {
        data: labelsData,
        isLoading,
        isError,
    } = useQuery({
        queryKey: ['projectLabels', project?.name],
        queryFn: async () => {
            const resp = await projectLabels({ path: { project_name: project!.name } });
            const raw = resp.data?.data;
            if (!raw) return [];
            if (Array.isArray(raw)) return raw;
            // Try to extract items from paginated response
            const keys = Object.keys(raw);
            for (const key of keys) {
                if (Array.isArray((raw as Record<string, unknown>)[key])) {
                    return (raw as Record<string, unknown>)[key];
                }
            }
            return [];
        },
        enabled: !!project?.name,
    });

    const labels = Array.isArray(labelsData)
        ? labelsData
        : [];

    const createMutation = useMutation({
        mutationFn: async () => {
            await projectCreateLabel({
                path: { project_name: project!.name },
                body: { name, color, description: desc },
            });
        },
        onSuccess: () => {
            toast.success('Label created');
            queryClient.invalidateQueries({ queryKey: ['projectLabels', project?.name] });
            resetForm();
        },
        onError: (err: unknown) => {
            toast.error(
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                getApiErrorMessage(err, 'Failed to create label'),
            );
        },
    });

    const updateMutation = useMutation({
        mutationFn: async () => {
            if (!editingId) return;
            await projectUpdateLabel({
                path: { project_name: project!.name, label_id: editingId },
                body: { name: name || null, color: color || null, description: desc || null },
            });
        },
        onSuccess: () => {
            toast.success('Label updated');
            queryClient.invalidateQueries({ queryKey: ['projectLabels', project!.name] });
            resetForm();
        },
        onError: (err: unknown) => {
            toast.error(
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                getApiErrorMessage(err, 'Failed to update label'),
            );
        },
    });

    const deleteMutation = useMutation({
        mutationFn: async () => {
            if (!deletingId) return;
            await projectDeleteLabel({
                path: { project_name: project!.name, label_id: deletingId },
            });
        },
        onSuccess: () => {
            toast.success('Label deleted');
            queryClient.invalidateQueries({ queryKey: ['projectLabels', project!.name] });
            setDeletingId(null);
        },
        onError: (err: unknown) => {
            toast.error(
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                getApiErrorMessage(err, 'Failed to delete label'),
            );
        },
    });

    const resetForm = () => {
        setName('');
        setColor('#3b82f6');
        setDesc('');
        setEditingId(null);
        setShowForm(false);
    };

    const handleEdit = (label: { id: number; name: string; color: string; description?: string }) => {
        setEditingId(label.id);
        setName(label.name || '');
        setColor(label.color || '#3b82f6');
        setDesc(label.description || '');
        setShowForm(true);
    };

    const handleSubmit = (e: React.FormEvent) => {
        e.preventDefault();
        if (!name.trim()) {
            toast.error('Label name is required');
            return;
        }
        if (editingId) {
            updateMutation.mutate();
        } else {
            createMutation.mutate();
        }
    };

    if (!project) return null;

    return (
        <div className="space-y-6">
            <Card>
                <CardHeader>
                    <CardTitle className="flex items-center gap-2">
                        <Hash className="h-5 w-5" />
                        Labels
                    </CardTitle>
                    <CardDescription>
                        Manage project labels for organizing issues.
                    </CardDescription>
                </CardHeader>

                <CardContent className="space-y-6">
                    {showForm && (
                        <Card className="border-primary">
                            <CardHeader className="pb-4">
                                <CardTitle className="text-base">
                                    {editingId ? 'Edit Label' : 'Create Label'}
                                </CardTitle>
                            </CardHeader>
                            <CardContent>
                                <form onSubmit={handleSubmit} className="space-y-4">
                                    <div className="space-y-2">
                                        <Label>Name *</Label>
                                        <Input
                                            value={name}
                                            onChange={(e) => setName(e.target.value)}
                                            placeholder="Label name"
                                            disabled={createMutation.isPending || updateMutation.isPending}
                                        />
                                    </div>
                                    <div className="space-y-2">
                                        <Label>Color</Label>
                                        <div className="flex items-center gap-2">
                                            <input
                                                type="color"
                                                value={color}
                                                onChange={(e) => setColor(e.target.value)}
                                                className="w-12 h-10 border rounded cursor-pointer"
                                            />
                                            <Input
                                                value={color}
                                                onChange={(e) => setColor(e.target.value)}
                                                className="w-32"
                                                disabled={createMutation.isPending || updateMutation.isPending}
                                            />
                                        </div>
                                    </div>
                                    <div className="space-y-2">
                                        <Label>Description</Label>
                                        <Textarea
                                            value={desc}
                                            onChange={(e) => setDesc(e.target.value)}
                                            placeholder="Describe this label"
                                            rows={2}
                                            disabled={createMutation.isPending || updateMutation.isPending}
                                        />
                                    </div>
                                    <div className="flex justify-end gap-2">
                                        <Button
                                            type="button"
                                            variant="outline"
                                            onClick={resetForm}
                                            disabled={createMutation.isPending || updateMutation.isPending}
                                        >
                                            Cancel
                                        </Button>
                                        <Button
                                            type="submit"
                                            disabled={createMutation.isPending || updateMutation.isPending}
                                        >
                                            {(createMutation.isPending || updateMutation.isPending) && (
                                                <span className="mr-2 h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent" />
                                            )}
                                            {editingId ? 'Update Label' : 'Create Label'}
                                        </Button>
                                    </div>
                                </form>
                            </CardContent>
                        </Card>
                    )}

                    {!showForm && (
                        <Button onClick={resetForm} className="mb-4">
                            <Plus className="mr-2 h-4 w-4" />
                            Add Label
                        </Button>
                    )}

                    {isLoading ? (
                        <div className="flex items-center justify-center h-32">
                            <Spinner />
                        </div>
                    ) : isError ? (
                        <p className="text-sm text-destructive text-center py-4">
                            Failed to load labels
                        </p>
                    ) : labels.length === 0 ? (
                        <p className="text-sm text-muted-foreground text-center py-6">
                            No labels found. Create your first label.
                        </p>
                    ) : (
                        <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
                            {labels.map(
                                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                                (label: any) => (
                                    <div
                                        key={label.id}
                                        className="flex items-center justify-between p-4 border rounded-lg hover:bg-muted/50 transition-colors group"
                                    >
                                        <div className="flex items-center gap-3 min-w-0">
                                            <div
                                                className="w-4 h-4 rounded-full shrink-0"
                                                style={{ backgroundColor: label.color || '#3b82f6' }}
                                            />
                                            <div className="min-w-0">
                                                <div className="font-medium truncate">{label.name}</div>
                                                {label.description && (
                                                    <p className="text-xs text-muted-foreground truncate">
                                                        {label.description}
                                                    </p>
                                                )}
                                            </div>
                                        </div>
                                        <div className="flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
                                            <Button
                                                variant="ghost"
                                                size="icon"
                                                className="h-8 w-8"
                                                onClick={() => handleEdit(label)}
                                            >
                                                <Edit3 className="h-4 w-4" />
                                            </Button>
                                            <Button
                                                variant="ghost"
                                                size="icon"
                                                className="h-8 w-8 text-destructive hover:text-destructive"
                                                onClick={() => setDeletingId(label.id)}
                                            >
                                                <Trash2 className="h-4 w-4" />
                                            </Button>
                                        </div>
                                    </div>
                                ),
                            )}
                        </div>
                    )}
                </CardContent>
            </Card>

            <AlertDialog open={!!deletingId} onOpenChange={(open) => !open && setDeletingId(null)}>
                <AlertDialogContent>
                    <AlertDialogHeader>
                        <AlertDialogTitle>Delete label</AlertDialogTitle>
                        <AlertDialogDescription>
                            Are you sure you want to delete this label? This action cannot be undone.
                        </AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                        <AlertDialogCancel disabled={deleteMutation.isPending}>Cancel</AlertDialogCancel>
                        <AlertDialogAction
                            onClick={() => deleteMutation.mutate()}
                            className="bg-destructive hover:bg-destructive/90"
                            disabled={deleteMutation.isPending}
                        >
                            Delete
                        </AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>
        </div>
    );
}
