import { useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from '@/components/ui/alert-dialog';
import { ArrowLeft } from 'lucide-react';
import { useMutation, useQuery } from '@tanstack/react-query';
import { toast } from 'sonner';
import { issueGet, issueUpdate, projectRepos } from '@/client';
import { useProject } from '@/contexts';
import type { RepoLike } from './types';
import { Button } from '@/components/ui/button';
import { Spinner } from '@/components/ui/spinner';
import { Textarea } from '@/components/ui/textarea';
import {getApiErrorMessage} from '@/lib/api-error';

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

export function IssueEdit() {
    const { project } = useProject();
    const { issueNumber } = useParams<{ issueNumber: string }>();
    const navigate = useNavigate();

    const no = Number(issueNumber || 0);
    const [showCancelConfirm, setShowCancelConfirm] = useState(false);

    const { data: issue, isLoading } = useQuery({
        queryKey: ['projectIssueDetail', project?.name, no],
        queryFn: async () => {
            const resp = await issueGet({
                path: { project: project!.name, number: no },
            });
            return resp.data?.data ?? null;
        },
        enabled: !!project?.name && !!no,
    });

    // Repositories
    const { data: reposData } = useQuery({
        queryKey: ['projectReposForIssueEdit', 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[];

    const [body, setBody] = useState('');
    const [selectedRepoUids, setSelectedRepoUids] = useState<string[]>([]);
    const [originalBody, setOriginalBody] = useState('');

    useEffect(() => {
        if (issue) {
            setBody(issue.body || '');
            setOriginalBody(issue.body || '');
        }
    }, [issue]);

    const hasChanges = body !== originalBody;

    const updateMutation = useMutation({
        mutationFn: async () => {
            await issueUpdate({
                path: { project: project!.name, number: no },
                body: {
                    title: issue?.title || '',
                    body: body.trim() || null,
                },
            });
        },
        onSuccess: () => {
            toast.success('Issue updated successfully');
            navigate(`/project/${project!.name}/issues/${no}`);
        },
        onError: (err: unknown) => {
            toast.error(getApiErrorMessage(err, 'Failed to update issue'));
        },
    });

    if (!project) return null;

    if (isLoading) {
        return (
            <div className="flex items-center justify-center h-64">
                <Spinner />
            </div>
        );
    }

    if (!issue) {
        return (
            <div className="p-6">
                <div className="rounded-lg border border-destructive/30 bg-destructive/10 p-4 text-destructive text-sm">
                    Issue not found.
                </div>
            </div>
        );
    }

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

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

    const confirmCancel = () => {
        setShowCancelConfirm(false);
        navigate(`/project/${project.name}/issues/${no}`);
    };

    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}
                        title="Return to issue"
                        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 Issue #{no}
                    </button>
                    <span className="text-xs text-muted-foreground">
                        Editing issue <span className="font-medium text-foreground">#{no}</span>
                    </span>
                </div>
            </div>

            <div className="max-w-3xl mx-auto px-6 py-6">
                <h1 className="mb-6 text-xl font-semibold">
                    Edit Issue <span className="text-muted-foreground">#{no}</span>
                </h1>

                <div className="space-y-5">
                    {/* Title (read-only) */}
                    <div className="rounded-lg border overflow-hidden">
                        <div className="px-4 py-2.5 border-b bg-muted/40">
                            <span className="text-xs font-medium text-foreground">Title</span>
                        </div>
                        <div className="p-4">
                            <h2 className="text-base font-medium text-foreground/90">{issue.title}</h2>
                            <p className="mt-1 text-xs text-muted-foreground">
                                Title cannot be changed after creation
                            </p>
                        </div>
                    </div>

                    {/* Status */}
                    <div className="rounded-lg border overflow-hidden">
                        <div className="px-4 py-2.5 border-b bg-muted/40">
                            <span className="text-xs font-medium text-foreground">Status</span>
                        </div>
                        <div className="p-4">
                            <div className="flex items-center gap-3">
                                <span
                                    className={`inline-flex items-center px-2.5 py-1 rounded-md text-xs font-medium border ${
                                        issue.state === 'open'
                                            ? 'bg-emerald-50 text-emerald-700 border-emerald-200 dark:bg-emerald-950/40 dark:text-emerald-400 dark:border-emerald-800'
                                            : 'bg-violet-50 text-violet-700 border-violet-200 dark:bg-violet-950/40 dark:text-violet-400 dark:border-violet-800'
                                    }`}
                                >
                                    {issue.state === 'open' ? 'Open' : 'Closed'}
                                </span>
                                <span className="text-xs text-muted-foreground">
                                    Change status from the issue detail page
                                </span>
                            </div>
                        </div>
                    </div>

                    {/* Description */}
                    <div className="rounded-lg border overflow-hidden">
                        <div className="px-4 py-2.5 border-b bg-muted/40">
                            <label htmlFor="issue-body" className="text-xs font-medium text-foreground">
                                Description
                            </label>
                        </div>
                        <div className="p-4">
                            <Textarea
                                id="issue-body"
                                value={body}
                                onChange={(e) => setBody(e.target.value)}
                                rows={10}
                                className="resize-none text-sm leading-relaxed"
                                placeholder="Add a description to provide more context (supports Markdown)"
                            />
                            <p className="mt-2 text-xs text-muted-foreground">
                                Supports Markdown formatting
                            </p>
                        </div>
                    </div>

                    {/* Linked Repositories */}
                    <div className="rounded-lg border overflow-hidden">
                        <div className="px-4 py-2.5 border-b bg-muted/40">
                            <span className="text-xs font-medium text-foreground">Linked Repositories</span>
                        </div>
                        <div className="max-h-48 overflow-y-auto p-3">
                            {repositories.length === 0 ? (
                                <div className="py-4 text-center">
                                    <p className="text-sm text-muted-foreground">
                                        No repositories in this project
                                    </p>
                                </div>
                            ) : (
                                <div className="space-y-1">
                                    {repositories.map((repo) => {
                                        const uid = getRepoUid(repo);
                                        return (
                                            <label
                                                key={uid}
                                                className="flex cursor-pointer items-center gap-3 rounded-md px-3 py-2 hover:bg-muted/60 transition-colors"
                                            >
                                                <input
                                                    type="checkbox"
                                                    checked={selectedRepoUids.includes(uid)}
                                                    onChange={() => toggleRepo(uid)}
                                                    className="h-4 w-4 rounded border-input accent-primary"
                                                />
                                                <span className="text-sm font-medium text-foreground/90">{repo.repo_name}</span>
                                                {repo.description && (
                                                    <span className="truncate text-xs text-muted-foreground">
                                                        — {repo.description}
                                                    </span>
                                                )}
                                            </label>
                                        );
                                    })}
                                </div>
                            )}
                        </div>
                    </div>

                    {/* Actions */}
                    <div className="flex justify-end gap-3 pt-2">
                        <Button
                            variant="outline"
                            onClick={handleCancel}
                            disabled={updateMutation.isPending}
                        >
                            Cancel
                        </Button>
                        <Button
                            onClick={() => updateMutation.mutate()}
                            disabled={updateMutation.isPending || !hasChanges}
                        >
                            {updateMutation.isPending ? 'Saving…' : 'Save Changes'}
                        </Button>
                    </div>
                </div>
            </div>

            <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={confirmCancel}>
                            Discard
                        </AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>
        </div>
    );
}
