import {useCallback, useEffect, useState} from 'react';
import {useNavigate} from 'react-router-dom';
import {useQuery} from '@tanstack/react-query';
import {CheckCircle2, Loader2, XCircle} from 'lucide-react';
import {toast} from 'sonner';
import {projectCreate, projectInfo, workspaceList} from '@/client';
import {Button} from '@/components/ui/button';
import {Input} from '@/components/ui/input';
import {Label} from '@/components/ui/label';
import {Switch} from '@/components/ui/switch';
import {Textarea} from '@/components/ui/textarea';
import {validateName} from '@/lib/validation';
import {InitLayout} from '@/components/init-layout';
import {getApiErrorMessage} from '@/lib/api-error';

export function InitProject() {
    const navigate = useNavigate();
    const [isLoading, setIsLoading] = useState(false);

    const [name, setName] = useState('');
    const [description, setDescription] = useState('');
    const [isPublic, setIsPublic] = useState(false);
    const [workspaceSlug, setWorkspaceSlug] = useState<string>('');

    const [checkingAvailability, setCheckingAvailability] = useState(false);
    const [nameAvailable, setNameAvailable] = useState<boolean | null>(null);
    const [availabilityMessage, setAvailabilityMessage] = useState('');

    const {data: workspacesData} = useQuery({
        queryKey: ['workspaceListForProject'],
        queryFn: async () => {
            const resp = await workspaceList();
            return resp.data?.data ?? null;
        },
    });

    // Pre-select first workspace if available
    useEffect(() => {
        if (workspacesData?.workspaces?.length) {
            setWorkspaceSlug(workspacesData.workspaces[0].slug);
        }
    }, [workspacesData]);

    const checkNameAvailability = useCallback(async () => {
        if (!name.trim()) {
            setNameAvailable(null);
            setAvailabilityMessage('');
            return;
        }

        const result = validateName(name.trim());
        if (!result.valid) {
            setNameAvailable(false);
            setAvailabilityMessage(result.message);
            return;
        }

        setCheckingAvailability(true);
        try {
            const lower = name.trim().toLowerCase();
            const resp = await projectInfo({path: {project_name: lower}});
            if (resp.error) {
                setNameAvailable(true);
                setAvailabilityMessage('Project name is available');
            } else {
                setNameAvailable(false);
                setAvailabilityMessage('Project name already exists');
            }

        } catch (_err: unknown) {
            setNameAvailable(true);
            setAvailabilityMessage('Project name is available');
        } finally {
            setCheckingAvailability(false);
        }
    }, [name]);

    useEffect(() => {
        const timer = setTimeout(() => {
            checkNameAvailability();
        }, 500);
        return () => clearTimeout(timer);
    }, [checkNameAvailability]);

    const handleSubmit = async (e: React.FormEvent) => {
        e.preventDefault();
        if (!name.trim()) {
            toast.error('Project name is required');
            return;
        }
        const result = validateName(name.trim());
        if (!result.valid) {
            toast.error(result.message);
            return;
        }

        setIsLoading(true);
        try {
            const resp = await projectCreate({
                body: {
                    name: name.trim().toLowerCase(),
                    description: description.trim() || null,
                    is_public: isPublic,
                    workspace_slug: workspaceSlug || null,
                },
            });
            if (resp.data?.code !== 0) {
                toast.error(resp.data?.message || 'Failed to create project');
                return;
            }
            const projectName = resp.data?.data?.project?.name;
            const wsSlug = resp.data?.data?.project?.workspace_id ? workspaceSlug : undefined;
            toast.success('Project created successfully!');
            if (wsSlug) {
                navigate(`/w/${wsSlug}/projects`);
            } else {
                navigate(projectName ? `/project/${projectName}` : '/');
            }
        } catch (err: unknown) {
            toast.error(getApiErrorMessage(err, 'Failed to create project'));
        } finally {
            setIsLoading(false);
        }
    };

    const canSubmit =
        !isLoading &&
        !!name.trim() &&
        nameAvailable === true &&
        !checkingAvailability;

    return (
        <InitLayout>
            <div className="w-full max-w-2xl">
                <form onSubmit={handleSubmit} className="bg-white dark:bg-[#1a1a2e] rounded-xl border p-8 shadow-md">
                    <div>
                        <h1 className="mb-1 mt-4 text-2xl font-semibold">Create New Project</h1>
                        <p className="text-sm text-muted-foreground">
                            Create a new project to organize your repositories
                        </p>
                    </div>

                    <hr className="my-6 border-dashed"/>

                    <div className="space-y-6">
                        <div className="space-y-2">
                            <Label htmlFor="name" className="block text-sm">
                                Project Name <span className="text-destructive">*</span>
                            </Label>
                            <div className="relative">
                                <Input
                                    type="text"
                                    id="name"
                                    placeholder="my-awesome-project"
                                    value={name}
                                    onChange={(e) => setName(e.target.value)}
                                    disabled={isLoading}
                                    maxLength={100}
                                    className="pr-10"
                                />
                                <div className="absolute right-3 top-1/2 -translate-y-1/2">
                                    {checkingAvailability && (
                                        <Loader2 className="h-4 w-4 animate-spin text-muted-foreground"/>
                                    )}
                                    {!checkingAvailability && nameAvailable === true && (
                                        <CheckCircle2 className="h-4 w-4 text-green-500"/>
                                    )}
                                    {!checkingAvailability && nameAvailable === false && (
                                        <XCircle className="h-4 w-4 text-destructive"/>
                                    )}
                                </div>
                            </div>
                            {availabilityMessage && (
                                <p
                                    className={`text-sm ${
                                        nameAvailable ? 'text-green-600 dark:text-green-400' : 'text-destructive'
                                    }`}
                                >
                                    {availabilityMessage}
                                </p>
                            )}
                        </div>

                        <div className="space-y-2">
                            <Label htmlFor="description" className="block text-sm">
                                Description
                            </Label>
                            <Textarea
                                id="description"
                                placeholder="A brief description of your project..."
                                rows={4}
                                value={description}
                                onChange={(e) => setDescription(e.target.value)}
                                disabled={isLoading}
                                className="resize-none"
                            />
                        </div>

                        {workspacesData?.workspaces && workspacesData.workspaces.length > 0 && (
                            <div className="space-y-2">
                                <Label htmlFor="workspace" className="block text-sm">
                                    Workspace
                                </Label>
                                <select
                                    id="workspace"
                                    className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
                                    value={workspaceSlug}
                                    onChange={(e) => setWorkspaceSlug(e.target.value)}
                                    disabled={isLoading}
                                >
                                    <option value="">No workspace (independent project)</option>
                                    {workspacesData.workspaces.map((ws) => (
                                        <option key={ws.slug} value={ws.slug}>
                                            {ws.name}
                                        </option>
                                    ))}
                                </select>
                                <p className="text-xs text-muted-foreground">
                                    Optionally associate this project with a workspace.
                                </p>
                            </div>
                        )}

                        <div className="flex items-center justify-between rounded-lg border p-4">
                            <div className="space-y-0.5">
                                <Label htmlFor="is_public" className="text-sm font-medium">
                                    Public Project
                                </Label>
                                <p className="text-sm text-muted-foreground">
                                    Make this project visible to everyone
                                </p>
                            </div>
                            <Switch
                                id="is_public"
                                checked={isPublic}
                                onCheckedChange={setIsPublic}
                                disabled={isLoading}
                            />
                        </div>

                        <div className="flex gap-4 pt-4">
                            <Button
                                type="submit"
                                className="flex-1"
                                disabled={canSubmit === false}
                            >
                                {isLoading ? 'Creating...' : 'Create Project'}
                            </Button>
                            <Button
                                type="button"
                                variant="outline"
                                onClick={() => navigate(-1)}
                                disabled={isLoading}
                            >
                                Cancel
                            </Button>
                        </div>
                    </div>
                </form>
            </div>
        </InitLayout>
    );
}
