import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import {
    AlertDialog,
    AlertDialogAction,
    AlertDialogCancel,
    AlertDialogContent,
    AlertDialogDescription,
    AlertDialogFooter,
    AlertDialogHeader,
    AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import {
    Dialog,
    DialogContent,
    DialogHeader,
    DialogTitle,
    DialogDescription,
    DialogFooter,
} from '@/components/ui/dialog';
import {
    ArrowLeft,
    Loader2,
    Plus,
    Tags,
    Users,
    GitBranch,
    Bold,
    Italic,
    Code,
    Link2,
    List,
    Quote,
} from 'lucide-react';
import { useMutation, useQuery } from '@tanstack/react-query';
import { toast } from 'sonner';
import { issueCreate, labelList, projectMembers, projectRepos } from '@/client';
import { useProject } from '@/contexts';
import type { RepoLike } from './types';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import {getApiErrorMessage} from '@/lib/api-error';

const TITLE_MAX = 100;

const getRepoUid = (repo: RepoLike): string =>
    repo.uid || (repo as unknown as { repo_uid?: string }).repo_uid || repo.repo_name;

export function IssueNew() {
    const { project } = useProject();
    const navigate = useNavigate();

    const [title, setTitle] = useState('');
    const [body, setBody] = useState('');
    const [selectedRepoUids, setSelectedRepoUids] = useState<string[]>([]);
    const [selectedAssignees, setSelectedAssignees] = useState<string[]>([]);
    const [selectedLabelIds, setSelectedLabelIds] = useState<number[]>([]);
    const [assigneesOpen, setAssigneesOpen] = useState(false);
    const [labelsOpen, setLabelsOpen] = useState(false);
    const [showCancelConfirm, setShowCancelConfirm] = useState(false);

    const hasChanges = title.trim().length > 0 || body.trim().length > 0;

    // Repositories
    const { data: reposData } = useQuery({
        queryKey: ['projectReposForIssueNew', project?.name],
        queryFn: async () => {
            const resp = await projectRepos({ path: { project_name: project!.name } });
            return resp.data?.data;
        },
        enabled: !!project?.name,
    });
    const repositories: RepoLike[] = (reposData?.items || []) as RepoLike[];

    // Members (assignees)
    const { data: membersData, isLoading: membersLoading } = useQuery({
        queryKey: ['projectMembersForIssue', project?.name],
        queryFn: async () => {
            const resp = await projectMembers({ path: { project_name: project!.name } });
            return resp.data?.data;
        },
        enabled: !!project?.name,
    });
    const members: { user_id: string; username?: string; display_name?: string; avatar_url?: string }[] =
        ((membersData as unknown) as { members?: typeof members })?.members ?? [];

    // Labels
    const { data: labelsData, isLoading: labelsLoading } = useQuery({
        queryKey: ['projectLabelsForIssue', project?.name],
        queryFn: async () => {
            const resp = await labelList({ path: { project: project!.name } });
            return resp.data?.data;
        },
        enabled: !!project?.name,
    });
    const labels: { id: number; name: string; description?: string | null; color?: string | null }[] =
        (labelsData as { labels?: typeof labelsData })?.labels ?? [];

    const createMutation = useMutation({
        mutationFn: async () => {
            const resp = await issueCreate({
                path: { project: project!.name },
                body: {
                    title: title.trim(),
                    body: body.trim() || null,
                },
            });
            return resp.data?.data;
        },
        onSuccess: (data) => {
            toast.success('Issue created');
            if (data?.number) {
                navigate(`/project/${project!.name}/issues/${data.number}`);
            } else {
                navigate(`/project/${project!.name}/issues`);
            }
        },
        onError: (err: unknown) => {
            toast.error(getApiErrorMessage(err, 'Failed to create issue'));
        },
    });

    if (!project) return null;

    const handleSubmit = () => {
        if (!title.trim()) {
            toast.error('Title is required');
            return;
        }
        createMutation.mutate();
    };

    const handleCancel = () => {
        if (hasChanges) {
            setShowCancelConfirm(true);
        } else {
            navigate(`/project/${project.name}/issues`);
        }
    };

    const toggleRepo = (uid: string) => {
        setSelectedRepoUids((prev) =>
            prev.includes(uid) ? prev.filter((v) => v !== uid) : [...prev, uid],
        );
    };

    const toggleAssignee = (userId: string) => {
        setSelectedAssignees((prev) =>
            prev.includes(userId) ? prev.filter((v) => v !== userId) : [...prev, userId],
        );
    };

    const toggleLabel = (labelId: number) => {
        setSelectedLabelIds((prev) =>
            prev.includes(labelId) ? prev.filter((v) => v !== labelId) : [...prev, labelId],
        );
    };

    return (
        <div className="flex-1 overflow-auto">
            {/* Header */}
            <div className="border-b">
                <div className="flex items-center justify-between px-6 py-3">
                    <button
                        onClick={handleCancel}
                        className="flex items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground transition-colors"
                    >
                        <ArrowLeft className="h-4 w-4" />
                        Back to Issues
                    </button>
                    <span className="text-xs text-muted-foreground">
                        Creating in{' '}
                        <span className="font-medium text-foreground">{project.name}</span>
                    </span>
                </div>
            </div>

            <div className="max-w-3xl mx-auto px-6 py-8 space-y-6">
                {/* Title */}
                <div>
                    <label className="text-sm font-semibold text-foreground">
                        Title <span className="text-destructive">*</span>
                    </label>
                    <div className="mt-1.5 relative">
                        <Input
                            value={title}
                            onChange={(e) => setTitle(e.target.value.slice(0, TITLE_MAX))}
                            placeholder="Brief summary of the issue"
                            className="h-12 text-base pr-16"
                            autoFocus
                        />
                        <span
                            className={`absolute right-3 top-1/2 -translate-y-1/2 text-xs ${
                                title.length > TITLE_MAX * 0.9
                                    ? 'text-yellow-500'
                                    : 'text-muted-foreground'
                            }`}
                        >
                            {title.length}/{TITLE_MAX}
                        </span>
                    </div>
                </div>

                {/* Description */}
                <div>
                    <div className="flex items-center justify-between mb-1.5">
                        <label className="text-sm font-semibold text-foreground">
                            Description
                        </label>
                        {/* Markdown toolbar hint */}
                        <div className="flex items-center gap-0.5 text-muted-foreground">
                            <span className="text-[10px] uppercase tracking-wider mr-1">Markdown</span>
                            <button
                                type="button"
                                className="p-1 rounded hover:bg-muted transition-colors"
                                title="Bold"
                            >
                                <Bold className="h-3 w-3" />
                            </button>
                            <button
                                type="button"
                                className="p-1 rounded hover:bg-muted transition-colors"
                                title="Italic"
                            >
                                <Italic className="h-3 w-3" />
                            </button>
                            <button
                                type="button"
                                className="p-1 rounded hover:bg-muted transition-colors"
                                title="Code"
                            >
                                <Code className="h-3 w-3" />
                            </button>
                            <button
                                type="button"
                                className="p-1 rounded hover:bg-muted transition-colors"
                                title="Link"
                            >
                                <Link2 className="h-3 w-3" />
                            </button>
                            <button
                                type="button"
                                className="p-1 rounded hover:bg-muted transition-colors"
                                title="List"
                            >
                                <List className="h-3 w-3" />
                            </button>
                            <button
                                type="button"
                                className="p-1 rounded hover:bg-muted transition-colors"
                                title="Quote"
                            >
                                <Quote className="h-3 w-3" />
                            </button>
                        </div>
                    </div>
                    <Textarea
                        value={body}
                        onChange={(e) => setBody(e.target.value)}
                        placeholder={`Describe the issue in detail. Markdown is supported.

**Steps to reproduce**
1.
2.
3.

**Expected behavior**


**Actual behavior**


**Screenshots**`}
                        rows={12}
                        className="resize-none text-sm leading-relaxed font-mono"
                    />
                    <p className="mt-1.5 text-xs text-muted-foreground">
                        Supports Markdown — use **bold**, `code`, lists, and more
                    </p>
                </div>

                {/* Linked Repositories */}
                {repositories.length > 0 && (
                    <div>
                        <label className="text-sm font-semibold text-foreground">
                            Linked Repositories
                        </label>
                        <p className="text-xs text-muted-foreground mt-0.5 mb-2">
                            Track commits and pull requests related to this issue
                        </p>
                        <div className="rounded-lg border overflow-hidden">
                            {repositories.map((repo) => {
                                const uid = getRepoUid(repo);
                                const checked = selectedRepoUids.includes(uid);
                                return (
                                    <label
                                        key={uid}
                                        className={`flex cursor-pointer items-center gap-3 px-4 py-3 hover:bg-muted/50 transition-colors ${
                                            checked ? 'bg-primary/5' : ''
                                        }`}
                                    >
                                        <div
                                            className={`h-4 w-4 rounded border flex items-center justify-center transition-colors ${
                                                checked
                                                    ? 'bg-primary border-primary'
                                                    : 'border-muted-foreground/40'
                                            }`}
                                        >
                                            {checked && (
                                                <svg
                                                    className="h-2.5 w-2.5 text-primary-foreground"
                                                    fill="none"
                                                    viewBox="0 0 24 24"
                                                    stroke="currentColor"
                                                    strokeWidth={3}
                                                >
                                                    <path
                                                        strokeLinecap="round"
                                                        strokeLinejoin="round"
                                                        d="M5 13l4 4L19 7"
                                                    />
                                                </svg>
                                            )}
                                        </div>
                                        <input
                                            type="checkbox"
                                            checked={checked}
                                            onChange={() => toggleRepo(uid)}
                                            className="sr-only"
                                        />
                                        <GitBranch className="h-4 w-4 text-muted-foreground shrink-0" />
                                        <div className="flex-1 min-w-0">
                                            <div className="text-sm font-medium">
                                                {repo.repo_name}
                                            </div>
                                            {repo.description && (
                                                <div className="text-xs text-muted-foreground truncate">
                                                    {repo.description}
                                                </div>
                                            )}
                                        </div>
                                    </label>
                                );
                            })}
                        </div>
                    </div>
                )}

                {/* Metadata row: Assignees + Labels */}
                <div className="grid grid-cols-2 gap-4">
                    {/* Assignees */}
                    <div className="rounded-lg border">
                        <button
                            onClick={() => setAssigneesOpen(true)}
                            className="w-full flex items-center justify-between px-4 py-3 hover:bg-muted/50 transition-colors"
                        >
                            <div className="flex items-center gap-2">
                                <Users className="h-4 w-4 text-muted-foreground" />
                                <span className="text-sm font-medium">Assignees</span>
                                {selectedAssignees.length > 0 && (
                                    <span className="ml-1 text-xs bg-primary/10 text-primary rounded-full px-1.5 py-0.5">
                                        {selectedAssignees.length}
                                    </span>
                                )}
                            </div>
                            <Plus className="h-4 w-4 text-muted-foreground" />
                        </button>
                    </div>

                    {/* Labels */}
                    <div className="rounded-lg border">
                        <button
                            onClick={() => setLabelsOpen(true)}
                            className="w-full flex items-center justify-between px-4 py-3 hover:bg-muted/50 transition-colors"
                        >
                            <div className="flex items-center gap-2">
                                <Tags className="h-4 w-4 text-muted-foreground" />
                                <span className="text-sm font-medium">Labels</span>
                                {selectedLabelIds.length > 0 && (
                                    <span className="ml-1 text-xs bg-primary/10 text-primary rounded-full px-1.5 py-0.5">
                                        {selectedLabelIds.length}
                                    </span>
                                )}
                            </div>
                            <Plus className="h-4 w-4 text-muted-foreground" />
                        </button>
                    </div>
                </div>

                {/* Actions */}
                <div className="flex items-center justify-between pt-4 border-t">
                    <button
                        onClick={handleCancel}
                        className="text-sm text-muted-foreground hover:text-foreground transition-colors"
                    >
                        Cancel
                    </button>
                    <div className="flex items-center gap-3">
                        <Button
                            variant="outline"
                            onClick={handleCancel}
                            disabled={createMutation.isPending}
                        >
                            Cancel
                        </Button>
                        <Button
                            onClick={handleSubmit}
                            disabled={createMutation.isPending || !title.trim()}
                        >
                            {createMutation.isPending ? (
                                <>
                                    <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                                    Creating…
                                </>
                            ) : (
                                'Create Issue'
                            )}
                        </Button>
                    </div>
                </div>
            </div>

            {/* Assignees Dialog */}
            <Dialog open={assigneesOpen} onOpenChange={setAssigneesOpen}>
                <DialogContent className="sm:max-w-md">
                    <DialogHeader>
                        <DialogTitle>Select Assignees</DialogTitle>
                        <DialogDescription>
                            Choose team members to assign to this issue
                        </DialogDescription>
                    </DialogHeader>
                    <div className="max-h-72 overflow-y-auto py-2">
                        {membersLoading ? (
                            <div className="flex justify-center py-8">
                                <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
                            </div>
                        ) : members.length === 0 ? (
                            <p className="py-8 text-center text-sm text-muted-foreground">
                                No members found in this project
                            </p>
                        ) : (
                            <div className="space-y-0.5 px-1">
                                {members.map((member) => {
                                    const isSelected = selectedAssignees.includes(member.user_id);
                                    return (
                                        <button
                                            key={member.user_id}
                                            onClick={() => toggleAssignee(member.user_id)}
                                            className={`w-full flex items-center gap-3 rounded-lg px-3 py-2.5 text-left hover:bg-muted transition-colors ${
                                                isSelected ? 'bg-primary/5' : ''
                                            }`}
                                        >
                                            <div
                                                className={`h-4 w-4 rounded border shrink-0 flex items-center justify-center transition-colors ${
                                                    isSelected
                                                        ? 'bg-primary border-primary'
                                                        : 'border-muted-foreground/40'
                                                }`}
                                            >
                                                {isSelected && (
                                                    <svg className="h-2.5 w-2.5 text-primary-foreground" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={3}>
                                                        <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
                                                    </svg>
                                                )}
                                            </div>
                                            {member.avatar_url ? (
                                                <Avatar className="h-7 w-7">
                                                    <AvatarImage src={member.avatar_url} />
                                                    <AvatarFallback className="text-xs">
                                                        {(member.display_name ||
                                                            member.username ||
                                                            member.user_id)[0]?.toUpperCase()}
                                                    </AvatarFallback>
                                                </Avatar>
                                            ) : (
                                                <Avatar className="h-7 w-7">
                                                    <AvatarFallback className="text-xs">
                                                        {(member.display_name ||
                                                            member.username ||
                                                            member.user_id)[0]?.toUpperCase()}
                                                    </AvatarFallback>
                                                </Avatar>
                                            )}
                                            <div className="flex-1 min-w-0">
                                                <div className="text-sm font-medium truncate">
                                                    {member.display_name || member.username}
                                                </div>
                                                <div className="text-xs text-muted-foreground truncate">
                                                    @{member.username}
                                                </div>
                                            </div>
                                        </button>
                                    );
                                })}
                            </div>
                        )}
                    </div>
                    <DialogFooter>
                        <Button size="sm" onClick={() => setAssigneesOpen(false)}>
                            Done
                        </Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>

            {/* Labels Dialog */}
            <Dialog open={labelsOpen} onOpenChange={setLabelsOpen}>
                <DialogContent className="sm:max-w-md">
                    <DialogHeader>
                        <DialogTitle>Select Labels</DialogTitle>
                        <DialogDescription>
                            Choose labels to categorize this issue
                        </DialogDescription>
                    </DialogHeader>
                    <div className="max-h-72 overflow-y-auto py-2">
                        {labelsLoading ? (
                            <div className="flex justify-center py-8">
                                <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
                            </div>
                        ) : labels.length === 0 ? (
                            <p className="py-8 text-center text-sm text-muted-foreground">
                                No labels in this project yet
                            </p>
                        ) : (
                            <div className="space-y-0.5 px-1">
                                {labels.map((label) => {
                                    const isSelected = selectedLabelIds.includes(label.id);
                                    return (
                                        <button
                                            key={label.id}
                                            onClick={() => toggleLabel(label.id)}
                                            className={`w-full flex items-center gap-3 rounded-lg px-3 py-2.5 text-left hover:bg-muted transition-colors ${
                                                isSelected ? 'bg-primary/5' : ''
                                            }`}
                                        >
                                            <div
                                                className={`h-4 w-4 rounded border shrink-0 flex items-center justify-center transition-colors ${
                                                    isSelected
                                                        ? 'bg-primary border-primary'
                                                        : 'border-muted-foreground/40'
                                                }`}
                                            >
                                                {isSelected && (
                                                    <svg className="h-2.5 w-2.5 text-primary-foreground" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={3}>
                                                        <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
                                                    </svg>
                                                )}
                                            </div>
                                            <span
                                                className="h-5 w-5 rounded border shrink-0"
                                                style={{
                                                    backgroundColor: label.color
                                                        ? `#${label.color}`
                                                        : '#888',
                                                }}
                                            />
                                            <div className="flex-1 min-w-0">
                                                <div className="text-sm font-medium">{label.name}</div>
                                                {label.description && (
                                                    <div className="text-xs text-muted-foreground truncate">
                                                        {label.description}
                                                    </div>
                                                )}
                                            </div>
                                        </button>
                                    );
                                })}
                            </div>
                        )}
                    </div>
                    <DialogFooter>
                        <Button size="sm" onClick={() => setLabelsOpen(false)}>
                            Done
                        </Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>

            {/* Cancel confirmation */}
            <AlertDialog open={showCancelConfirm} onOpenChange={setShowCancelConfirm}>
                <AlertDialogContent>
                    <AlertDialogHeader>
                        <AlertDialogTitle>Discard changes?</AlertDialogTitle>
                        <AlertDialogDescription>
                            You have unsaved changes. Are you sure you want to leave?
                        </AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                        <AlertDialogCancel>Keep editing</AlertDialogCancel>
                        <AlertDialogAction onClick={() => navigate(`/project/${project.name}/issues`)}>
                            Discard
                        </AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>
        </div>
    );
}
