import { zodResolver } from "@hookform/resolvers/zod"
import { Controller, useForm } from "react-hook-form"
import { z } from "zod"

import { Button } from "@/components/ui/button"
import {
    Form,
    FormControl,
    FormDescription,
    FormField,
    FormItem,
    FormLabel,
    FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { ScrollArea } from "@/components/ui/scroll-area"
import { Separator } from "@/components/ui/separator"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import React, { useEffect, useRef, useState } from "react"
import { Alert, AlertDescription } from "@/components/ui/alert"
import { toast } from "sonner"
import { createCredential, updateCredential, getCredentials } from '@/ui/main-axios'
import { useTranslation } from "react-i18next"

interface Credential {
    id: number;
    name: string;
    description?: string;
    folder?: string;
    tags: string[];
    authType: 'password' | 'key';
    username: string;
    keyType?: string;
    usageCount: number;
    lastUsed?: string;
    createdAt: string;
    updatedAt: string;
}

interface CredentialEditorProps {
    editingCredential?: Credential | null;
    onFormSubmit?: () => void;
}

export function CredentialEditor({ editingCredential, onFormSubmit }: CredentialEditorProps) {
    const { t } = useTranslation();
    const [credentials, setCredentials] = useState<Credential[]>([]);
    const [folders, setFolders] = useState<string[]>([]);
    const [loading, setLoading] = useState(true);

    const [authTab, setAuthTab] = useState<'password' | 'key'>('password');

    useEffect(() => {
        const fetchData = async () => {
            try {
                setLoading(true);
                const credentialsData = await getCredentials();
                setCredentials(credentialsData);

                const uniqueFolders = [...new Set(
                    credentialsData
                        .filter(credential => credential.folder && credential.folder.trim() !== '')
                        .map(credential => credential.folder)
                )].sort();

                setFolders(uniqueFolders);
            } catch (error) {
            } finally {
                setLoading(false);
            }
        };

        fetchData();
    }, []);

    const formSchema = z.object({
        name: z.string().min(1),
        description: z.string().optional(),
        folder: z.string().optional(),
        tags: z.array(z.string().min(1)).default([]),
        authType: z.enum(['password', 'key']),
        username: z.string().min(1),
        password: z.string().optional(),
        key: z.instanceof(File).optional().nullable(),
        keyPassword: z.string().optional(),
        keyType: z.enum([
            'rsa',
            'ecdsa',
            'ed25519'
        ]).optional(),
    }).superRefine((data, ctx) => {
        if (data.authType === 'password') {
            if (!data.password || data.password.trim() === '') {
                ctx.addIssue({
                    code: z.ZodIssueCode.custom,
                    message: t('credentials.passwordRequired'),
                    path: ['password']
                });
            }
        } else if (data.authType === 'key') {
            if (!data.key && !editingCredential) {
                ctx.addIssue({
                    code: z.ZodIssueCode.custom,
                    message: t('credentials.sshKeyRequired'),
                    path: ['key']
                });
            }
        }
    });

    type FormData = z.infer<typeof formSchema>;

    const form = useForm<FormData>({
        resolver: zodResolver(formSchema) as any,
        defaultValues: {
            name: editingCredential?.name || "",
            description: editingCredential?.description || "",
            folder: editingCredential?.folder || "",
            tags: editingCredential?.tags || [],
            authType: editingCredential?.authType || "password",
            username: editingCredential?.username || "",
            password: "",
            key: null,
            keyPassword: "",
            keyType: "rsa",
        }
    });

    useEffect(() => {
        if (editingCredential) {
            const defaultAuthType = editingCredential.key ? 'key' : 'password';

            setAuthTab(defaultAuthType);

            form.reset({
                name: editingCredential.name || "",
                description: editingCredential.description || "",
                folder: editingCredential.folder || "",
                tags: editingCredential.tags || [],
                authType: defaultAuthType as 'password' | 'key',
                username: editingCredential.username || "",
                password: "",
                key: null,
                keyPassword: "",
                keyType: (editingCredential.keyType as any) || "rsa",
            });
        } else {
            setAuthTab('password');

            form.reset({
                name: "",
                description: "",
                folder: "",
                tags: [],
                authType: "password",
                username: "",
                password: "",
                key: null,
                keyPassword: "",
                keyType: "rsa",
            });
        }
    }, [editingCredential, form]);

    const onSubmit = async (data: any) => {
        try {
            const formData = data as FormData;

            if (!formData.name || formData.name.trim() === '') {
                formData.name = formData.username;
            }

            if (editingCredential) {
                await updateCredential(editingCredential.id, formData);
                toast.success(t('credentials.credentialUpdatedSuccessfully', { name: formData.name }));
            } else {
                await createCredential(formData);
                toast.success(t('credentials.credentialAddedSuccessfully', { name: formData.name }));
            }

            if (onFormSubmit) {
                onFormSubmit();
            }

            window.dispatchEvent(new CustomEvent('credentials:changed'));
        } catch (error) {
            toast.error(t('credentials.failedToSaveCredential'));
        }
    };

    const [tagInput, setTagInput] = useState("");

    const [folderDropdownOpen, setFolderDropdownOpen] = useState(false);
    const folderInputRef = useRef<HTMLInputElement>(null);
    const folderDropdownRef = useRef<HTMLDivElement>(null);

    const folderValue = form.watch('folder');
    const filteredFolders = React.useMemo(() => {
        if (!folderValue) return folders;
        return folders.filter(f => f.toLowerCase().includes(folderValue.toLowerCase()));
    }, [folderValue, folders]);

    const handleFolderClick = (folder: string) => {
        form.setValue('folder', folder);
        setFolderDropdownOpen(false);
    };

    useEffect(() => {
        function handleClickOutside(event: MouseEvent) {
            if (
                folderDropdownRef.current &&
                !folderDropdownRef.current.contains(event.target as Node) &&
                folderInputRef.current &&
                !folderInputRef.current.contains(event.target as Node)
            ) {
                setFolderDropdownOpen(false);
            }
        }

        if (folderDropdownOpen) {
            document.addEventListener('mousedown', handleClickOutside);
        } else {
            document.removeEventListener('mousedown', handleClickOutside);
        }

        return () => {
            document.removeEventListener('mousedown', handleClickOutside);
        };
    }, [folderDropdownOpen]);

    const keyTypeOptions = [
        { value: 'rsa', label: t('credentials.keyTypeRSA') },
        { value: 'ecdsa', label: t('credentials.keyTypeECDSA') },
        { value: 'ed25519', label: t('credentials.keyTypeEd25519') },
    ];

    const [keyTypeDropdownOpen, setKeyTypeDropdownOpen] = useState(false);
    const keyTypeButtonRef = useRef<HTMLButtonElement>(null);
    const keyTypeDropdownRef = useRef<HTMLDivElement>(null);

    useEffect(() => {
        function onClickOutside(event: MouseEvent) {
            if (
                keyTypeDropdownOpen &&
                keyTypeDropdownRef.current &&
                !keyTypeDropdownRef.current.contains(event.target as Node) &&
                keyTypeButtonRef.current &&
                !keyTypeButtonRef.current.contains(event.target as Node)
            ) {
                setKeyTypeDropdownOpen(false);
            }
        }

        document.addEventListener("mousedown", onClickOutside);
        return () => document.removeEventListener("mousedown", onClickOutside);
    }, [keyTypeDropdownOpen]);

    return (
        <div className="flex-1 flex flex-col h-full min-h-0 w-full">
            <Form {...form}>
                <form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col flex-1 min-h-0 h-full">
                    <ScrollArea className="flex-1 min-h-0 w-full my-1 pb-2">
                        <Tabs defaultValue="general" className="w-full">
                            <TabsList>
                                <TabsTrigger value="general">{t('credentials.general')}</TabsTrigger>
                                <TabsTrigger value="authentication">{t('credentials.authentication')}</TabsTrigger>
                            </TabsList>
                            <TabsContent value="general" className="pt-2">
                                <FormLabel className="mb-3 font-bold">{t('credentials.basicInformation')}</FormLabel>
                                <div className="grid grid-cols-12 gap-4">
                                    <FormField
                                        control={form.control}
                                        name="name"
                                        render={({ field }) => (
                                            <FormItem className="col-span-6">
                                                <FormLabel>{t('credentials.credentialName')}</FormLabel>
                                                <FormControl>
                                                    <Input placeholder={t('placeholders.credentialName')} {...field} />
                                                </FormControl>
                                            </FormItem>
                                        )}
                                    />

                                    <FormField
                                        control={form.control}
                                        name="username"
                                        render={({ field }) => (
                                            <FormItem className="col-span-6">
                                                <FormLabel>{t('credentials.username')}</FormLabel>
                                                <FormControl>
                                                    <Input placeholder={t('placeholders.username')} {...field} />
                                                </FormControl>
                                            </FormItem>
                                        )}
                                    />
                                </div>
                                <FormLabel className="mb-3 mt-3 font-bold">{t('credentials.organization')}</FormLabel>
                                <div className="grid grid-cols-26 gap-4">
                                    <FormField
                                        control={form.control}
                                        name="description"
                                        render={({ field }) => (
                                            <FormItem className="col-span-10">
                                                <FormLabel>{t('credentials.description')}</FormLabel>
                                                <FormControl>
                                                    <Input placeholder={t('placeholders.description')} {...field} />
                                                </FormControl>
                                            </FormItem>
                                        )}
                                    />

                                    <FormField
                                        control={form.control}
                                        name="folder"
                                        render={({ field }) => (
                                            <FormItem className="col-span-10 relative">
                                                <FormLabel>{t('credentials.folder')}</FormLabel>
                                                <FormControl>
                                                    <Input
                                                        ref={folderInputRef}
                                                        placeholder={t('placeholders.folder')}
                                                        className="min-h-[40px]"
                                                        autoComplete="off"
                                                        value={field.value}
                                                        onFocus={() => setFolderDropdownOpen(true)}
                                                        onChange={e => {
                                                            field.onChange(e);
                                                            setFolderDropdownOpen(true);
                                                        }}
                                                    />
                                                </FormControl>
                                                {folderDropdownOpen && filteredFolders.length > 0 && (
                                                    <div
                                                        ref={folderDropdownRef}
                                                        className="absolute top-full left-0 z-50 mt-1 w-full bg-[#18181b] border border-input rounded-md shadow-lg max-h-40 overflow-y-auto p-1"
                                                    >
                                                        <div className="grid grid-cols-1 gap-1 p-0">
                                                            {filteredFolders.map((folder) => (
                                                                <Button
                                                                    key={folder}
                                                                    type="button"
                                                                    variant="ghost"
                                                                    size="sm"
                                                                    className="w-full justify-start text-left rounded px-2 py-1.5 hover:bg-white/15 focus:bg-white/20 focus:outline-none"
                                                                    onClick={() => handleFolderClick(folder)}
                                                                >
                                                                    {folder}
                                                                </Button>
                                                            ))}
                                                        </div>
                                                    </div>
                                                )}
                                            </FormItem>
                                        )}
                                    />

                                    <FormField
                                        control={form.control}
                                        name="tags"
                                        render={({ field }) => (
                                            <FormItem className="col-span-10 overflow-visible">
                                                <FormLabel>{t('credentials.tags')}</FormLabel>
                                                <FormControl>
                                                    <div
                                                        className="flex flex-wrap items-center gap-1 border border-input rounded-md px-3 py-2 bg-[#222225] focus-within:ring-2 ring-ring min-h-[40px]">
                                                        {field.value.map((tag: string, idx: number) => (
                                                            <span key={tag + idx}
                                                                  className="flex items-center bg-gray-200 text-gray-800 rounded-full px-2 py-0.5 text-xs">
                                                                {tag}
                                                                <button
                                                                    type="button"
                                                                    className="ml-1 text-gray-500 hover:text-red-500 focus:outline-none"
                                                                    onClick={() => {
                                                                        const newTags = field.value.filter((_: string, i: number) => i !== idx);
                                                                        field.onChange(newTags);
                                                                    }}
                                                                >
                                                                    ×
                                                                </button>
                                                            </span>
                                                        ))}
                                                        <input
                                                            type="text"
                                                            className="flex-1 min-w-[60px] border-none outline-none bg-transparent p-0 h-6"
                                                            value={tagInput}
                                                            onChange={e => setTagInput(e.target.value)}
                                                            onKeyDown={e => {
                                                                if (e.key === " " && tagInput.trim() !== "") {
                                                                    e.preventDefault();
                                                                    if (!field.value.includes(tagInput.trim())) {
                                                                        field.onChange([...field.value, tagInput.trim()]);
                                                                    }
                                                                    setTagInput("");
                                                                } else if (e.key === "Backspace" && tagInput === "" && field.value.length > 0) {
                                                                    field.onChange(field.value.slice(0, -1));
                                                                }
                                                            }}
                                                            placeholder={t('credentials.addTagsSpaceToAdd')}
                                                        />
                                                    </div>
                                                </FormControl>
                                            </FormItem>
                                        )}
                                    />
                                </div>
                            </TabsContent>
                            <TabsContent value="authentication">
                                <FormLabel className="mb-3 font-bold">{t('credentials.authentication')}</FormLabel>
                                <Tabs
                                    value={authTab}
                                    onValueChange={(value) => {
                                        setAuthTab(value as 'password' | 'key');
                                        form.setValue('authType', value as 'password' | 'key');
                                        // Clear other auth fields when switching
                                        if (value === 'password') {
                                            form.setValue('key', null);
                                            form.setValue('keyPassword', '');
                                        } else if (value === 'key') {
                                            form.setValue('password', '');
                                        }
                                    }}
                                    className="flex-1 flex flex-col h-full min-h-0"
                                >
                                    <TabsList>
                                        <TabsTrigger value="password">{t('credentials.password')}</TabsTrigger>
                                        <TabsTrigger value="key">{t('credentials.key')}</TabsTrigger>
                                    </TabsList>
                                    <TabsContent value="password">
                                        <FormField
                                            control={form.control}
                                            name="password"
                                            render={({ field }) => (
                                                <FormItem>
                                                    <FormLabel>{t('credentials.password')}</FormLabel>
                                                    <FormControl>
                                                        <Input type="password" placeholder={t('placeholders.password')} {...field} />
                                                    </FormControl>
                                                </FormItem>
                                            )}
                                        />
                                    </TabsContent>
                                    <TabsContent value="key">
                                        <div className="grid grid-cols-15 gap-4">
                                            <Controller
                                                control={form.control}
                                                name="key"
                                                render={({ field }) => (
                                                    <FormItem className="col-span-4 overflow-hidden min-w-0">
                                                        <FormLabel>{t('credentials.sshPrivateKey')}</FormLabel>
                                                        <FormControl>
                                                            <div className="relative min-w-0">
                                                                <input
                                                                    id="key-upload"
                                                                    type="file"
                                                                    accept=".pem,.key,.txt,.ppk"
                                                                    onChange={(e) => {
                                                                        const file = e.target.files?.[0];
                                                                        field.onChange(file || null);
                                                                    }}
                                                                    className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
                                                                />
                                                                <Button
                                                                    type="button"
                                                                    variant="outline"
                                                                    className="w-full min-w-0 overflow-hidden px-3 py-2 text-left"
                                                                >
                                                                    <span className="block w-full truncate"
                                                                          title={field.value?.name || t('credentials.upload')}>
                                                                        {field.value ? (editingCredential ? t('credentials.updateKey') : field.value.name) : t('credentials.upload')}
                                                                    </span>
                                                                </Button>
                                                            </div>
                                                        </FormControl>
                                                    </FormItem>
                                                )}
                                            />
                                            <FormField
                                                control={form.control}
                                                name="keyPassword"
                                                render={({ field }) => (
                                                    <FormItem className="col-span-8">
                                                        <FormLabel>{t('credentials.keyPassword')}</FormLabel>
                                                        <FormControl>
                                                            <Input
                                                                placeholder={t('placeholders.keyPassword')}
                                                                type="password"
                                                                {...field}
                                                            />
                                                        </FormControl>
                                                    </FormItem>
                                                )}
                                            />
                                            <FormField
                                                control={form.control}
                                                name="keyType"
                                                render={({ field }) => (
                                                    <FormItem className="relative col-span-3">
                                                        <FormLabel>{t('credentials.keyType')}</FormLabel>
                                                        <FormControl>
                                                            <div className="relative">
                                                                <Button
                                                                    ref={keyTypeButtonRef}
                                                                    type="button"
                                                                    variant="outline"
                                                                    className="w-full justify-start text-left rounded-md px-2 py-2 bg-[#18181b] border border-input text-foreground"
                                                                    onClick={() => setKeyTypeDropdownOpen((open) => !open)}
                                                                >
                                                                    {keyTypeOptions.find((opt) => opt.value === field.value)?.label || t('credentials.keyTypeRSA')}
                                                                </Button>
                                                                {keyTypeDropdownOpen && (
                                                                    <div
                                                                        ref={keyTypeDropdownRef}
                                                                        className="absolute bottom-full left-0 z-50 mb-1 w-full bg-[#18181b] border border-input rounded-md shadow-lg max-h-40 overflow-y-auto p-1"
                                                                    >
                                                                        <div className="grid grid-cols-1 gap-1 p-0">
                                                                            {keyTypeOptions.map((opt) => (
                                                                                <Button
                                                                                    key={opt.value}
                                                                                    type="button"
                                                                                    variant="ghost"
                                                                                    size="sm"
                                                                                    className="w-full justify-start text-left rounded-md px-2 py-1.5 bg-[#18181b] text-foreground hover:bg-white/15 focus:bg-white/20 focus:outline-none"
                                                                                    onClick={() => {
                                                                                        field.onChange(opt.value);
                                                                                        setKeyTypeDropdownOpen(false);
                                                                                    }}
                                                                                >
                                                                                    {opt.label}
                                                                                </Button>
                                                                            ))}
                                                                        </div>
                                                                    </div>
                                                                )}
                                                            </div>
                                                        </FormControl>
                                                    </FormItem>
                                                )}
                                            />
                                        </div>
                                    </TabsContent>
                                </Tabs>
                            </TabsContent>
                        </Tabs>
                    </ScrollArea>
                    <footer className="shrink-0 w-full pb-0">
                        <Separator className="p-0.25"/>
                        <Button
                            className=""
                            type="submit"
                            variant="outline"
                            style={{
                                transform: 'translateY(8px)'
                            }}
                        >
                            {editingCredential ? t('credentials.updateCredential') : t('credentials.addCredential')}
                        </Button>
                    </footer>
                </form>
            </Form>
        </div>
    );
}