'use client'

import * as React from "react"
import { zodResolver } from "@hookform/resolvers/zod"
import { Loader } from "lucide-react"
import { useForm } from "react-hook-form"
import { toast } from "sonner"
import { z } from "zod"
import { useSession } from "next-auth/react"

import { Button } from "@/components/ui/button"
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from "@/components/ui/dialog"
import {
    Form,
    FormControl,
    FormDescription,
    FormField,
    FormItem,
    FormLabel,
    FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"

import { updateEmailWhitelistAction, type EmailWhitelist } from "../service"

// Validation Schema
const updateWhitelistSchema = z.object({
    value: z.string()
        .min(1, "값은 필수입니다")
        .max(255, "값은 255자를 초과할 수 없습니다")
        .refine((value) => {
            // 이메일 형식 또는 도메인 형식 중 하나여야 함
            const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

            // 도메인 검증: 최소 하나의 .이 있어야 하고, TLD가 있어야 함
            // 예: company.com, sub.company.com, company.co.kr
            const domainRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\.[a-zA-Z]{2,}$/;

            return emailRegex.test(value) || domainRegex.test(value);
        }, "올바른 이메일 주소 또는 도메인 형식이 아닙니다 (도메인은 최소 1개의 TLD가 필요합니다)"),
    description: z.string().max(500, "설명은 500자 이하여야 합니다").optional(),
})

type UpdateWhitelistSchema = z.infer<typeof updateWhitelistSchema>

interface UpdateWhitelistDialogProps
    extends React.ComponentPropsWithRef<typeof Dialog> {
    whitelist?: EmailWhitelist | null
}

export function UpdateWhitelistDialog({ whitelist, ...props }: UpdateWhitelistDialogProps) {
    const [isUpdatePending, startUpdateTransition] = React.useTransition()
    const { data: session } = useSession();

    const form = useForm<UpdateWhitelistSchema>({
        resolver: zodResolver(updateWhitelistSchema),
        defaultValues: {
            value: "",
            description: "",
        },
    })

    // 화이트리스트 데이터가 변경되면 폼 초기화
    React.useEffect(() => {
        if (whitelist) {
            form.reset({
                value: whitelist.displayValue || "",
                description: whitelist.description || "",
            })
        }
    }, [whitelist, form])

    // 입력값 소문자 변환
    React.useEffect(() => {
        const watchedValue = form.watch("value")
        if (watchedValue && watchedValue !== watchedValue.toLowerCase()) {
            form.setValue("value", watchedValue.toLowerCase())
        }
    }, [form])

    function onSubmit(input: UpdateWhitelistSchema) {
        startUpdateTransition(async () => {
            if (!session?.user?.id) {
                toast.error("로그인이 필요합니다")
                return
            }

            if (!whitelist) {
                toast.error("수정할 데이터를 찾을 수 없습니다")
                return
            }

            const { error } = await updateEmailWhitelistAction({
                id: whitelist.id,
                value: input.value,
                description: input.description,
            })

            if (error) {
                toast.error(error)
                return
            }

            props.onOpenChange?.(false)
            toast.success("화이트리스트 도메인이 수정되었습니다")
        })
    }

    return (
        <Dialog {...props}>
            <DialogContent className="sm:max-w-[425px]">
                <DialogHeader>
                    <DialogTitle>화이트리스트 수정</DialogTitle>
                    <DialogDescription>
                        화이트리스트 정보를 수정합니다.
                    </DialogDescription>
                </DialogHeader>
                <Form {...form}>
                    <form
                        onSubmit={form.handleSubmit(onSubmit)}
                        className="space-y-4"
                    >
                        <FormField
                            control={form.control}
                            name="value"
                            render={({ field }) => (
                                <FormItem>
                                    <FormLabel>이메일 주소 또는 도메인</FormLabel>
                                    <FormControl>
                                        <Input
                                            placeholder="예: user@company.com 또는 company.com"
                                            {...field}
                                        />
                                    </FormControl>
                                    <FormDescription>
                                        이메일 주소나 도메인을 입력하세요. @가 포함되면 개별 이메일로, 그렇지 않으면 도메인 전체로 등록됩니다. 도메인은 최소 1개의 TLD가 필요합니다.
                                    </FormDescription>
                                    <FormMessage />
                                </FormItem>
                            )}
                        />

                        <FormField
                            control={form.control}
                            name="description"
                            render={({ field }) => (
                                <FormItem>
                                    <FormLabel>설명 (선택사항)</FormLabel>
                                    <FormControl>
                                        <Textarea
                                            placeholder="도메인에 대한 설명을 입력하세요"
                                            className="min-h-[80px]"
                                            {...field}
                                        />
                                    </FormControl>
                                    <FormMessage />
                                </FormItem>
                            )}
                        />

                        <DialogFooter>
                            <Button
                                type="button"
                                variant="outline"
                                onClick={() => props.onOpenChange?.(false)}
                                disabled={isUpdatePending}
                            >
                                취소
                            </Button>
                            <Button disabled={isUpdatePending}>
                                {isUpdatePending && (
                                    <Loader
                                        className="mr-2 size-4 animate-spin"
                                        aria-hidden="true"
                                    />
                                )}
                                수정
                            </Button>
                        </DialogFooter>
                    </form>
                </Form>
            </DialogContent>
        </Dialog>
    )
}
