"use client"

import * as React from "react"
import { useForm, Controller } from "react-hook-form"
import { yupResolver } from "@hookform/resolvers/yup"
import * as yup from "yup"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { DatePicker } from "@/components/ui/date-picker"
import { Textarea } from "@/components/ui/textarea"
import {
    Dialog,
    DialogContent,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from "@/components/ui/dialog"
import { ReactSelect } from "@/components/ui/react-select"
import { Loader2 } from "lucide-react"
import { toast } from "sonner"
import type { Deal } from "@/api/rtk/deals-api"
import { useGetUsersQuery } from "@/api/rtk/users-api"
import {
    useCreateCustomerProjectMutation,
    useUpdateCustomerProjectMutation,
    type CustomerProjectRecord,
    type CustomerProjectStatus,
    type CreateCustomerProjectBody,
} from "@/api/rtk/customer-projects-api"
import { useAuthToken } from "@/hooks/use-auth-token"

const STATUSES: { value: CustomerProjectStatus; label: string }[] = [
    { value: "PLANNING", label: "Planning" },
    { value: "ACTIVE", label: "Active" },
    { value: "ON_HOLD", label: "On hold" },
    { value: "COMPLETED", label: "Completed" },
    { value: "CANCELLED", label: "Cancelled" },
]

const schema = yup.object().shape({
    name: yup.string().required("Project name is required"),
    description: yup
        .string()
        .required("Description is required")
        .min(100, "Description must be at least 100 characters"),
    status: yup.string().required("Status is required"),
    startDate: yup.string().nullable(),
    endDate: yup
        .string()
        .nullable()
        .test("date-range", "End date cannot be earlier than start date", function (value) {
            const { startDate } = this.parent
            if (startDate && value) {
                return new Date(value) >= new Date(startDate)
            }
            return true
        }),
    budgetValue: yup
        .number()
        .nullable()
        .transform((value, originalValue) => (originalValue === "" ? null : value))
        .typeError("Budget must be a valid number"),
    leadId: yup.string().nullable(),
    ownerId: yup.string().nullable(),
})

type FormData = yup.InferType<typeof schema>

function leadLabel(d: Deal): string {
    return (
        d.customerName?.trim() ||
        d.email?.trim() ||
        d.leadId?.trim() ||
        d.id.slice(0, 8) + "…"
    )
}

function toDateInput(iso: string | null | undefined): string {
    if (!iso) return ""
    const d = new Date(iso)
    if (isNaN(d.getTime())) return ""
    return d.toISOString().slice(0, 10)
}

export interface CustomerProjectDialogProps {
    open: boolean
    onOpenChange: (open: boolean) => void
    customerId: string
    linkedLeads: Deal[]
    project: CustomerProjectRecord | null
}

export function CustomerProjectDialog({
    open,
    onOpenChange,
    customerId,
    linkedLeads,
    project,
}: CustomerProjectDialogProps) {
    const { token } = useAuthToken()
    const {
        register,
        handleSubmit,
        control,
        reset,
        formState: { errors },
    } = useForm<FormData>({
        resolver: yupResolver(schema) as any,
        defaultValues: {
            name: "",
            description: "",
            status: "PLANNING",
            startDate: "",
            endDate: "",
            budgetValue: null,
            leadId: "",
            ownerId: "",
        },
    })

    const [createProject, { isLoading: creating }] =
        useCreateCustomerProjectMutation()
    const [updateProject, { isLoading: updating }] =
        useUpdateCustomerProjectMutation()
    const { data: usersResponse } = useGetUsersQuery(
        { limit: 300 },
        { skip: !open || !token }
    )
    const users = usersResponse?.data ?? []
    const isEdit = Boolean(project)
    const saving = creating || updating

    const statusOptions = React.useMemo(
        () => STATUSES.map((s) => ({ value: s.value, label: s.label })),
        [],
    )

    const leadOptions = React.useMemo(
        () => linkedLeads.map((d) => ({ value: d.id, label: leadLabel(d) })),
        [linkedLeads],
    )

    const ownerOptions = React.useMemo(
        () => users.map((u) => ({ value: u.id, label: u.name || u.email })),
        [users],
    )

    React.useEffect(() => {
        if (!open) return
        if (project) {
            reset({
                name: project.name,
                description: project.description ?? "",
                status: project.status,
                startDate: toDateInput(project.startDate),
                endDate: toDateInput(project.endDate),
                budgetValue:
                    project.budgetValue != null && project.budgetValue !== ""
                        ? Number(project.budgetValue)
                        : null,
                leadId: project.leadId ?? "",
                ownerId: project.ownerId ?? "",
            })
        } else {
            reset({
                name: "",
                description: "",
                status: "PLANNING",
                startDate: "",
                endDate: "",
                budgetValue: null,
                leadId: "",
                ownerId: "",
            })
        }
    }, [open, project, reset])

    const onSubmit = async (data: FormData) => {
        const body: CreateCustomerProjectBody = {
            name: data.name,
            description: data.description?.trim() || null,
            status: data.status as CustomerProjectStatus,
            startDate: data.startDate ? `${data.startDate}T12:00:00.000Z` : null,
            endDate: data.endDate ? `${data.endDate}T12:00:00.000Z` : null,
            budgetValue: data.budgetValue,
            leadId: data.leadId?.trim() ? data.leadId : null,
            ownerId: data.ownerId?.trim() ? data.ownerId : null,
        }
        try {
            if (isEdit && project) {
                await updateProject({
                    customerId,
                    projectId: project.id,
                    body,
                }).unwrap()
                toast.success("Project updated")
            } else {
                await createProject({ customerId, body }).unwrap()
                toast.success("Project created")
            }
            onOpenChange(false)
        } catch (err) {
            console.error(err)
            toast.error(
                isEdit ? "Could not update project" : "Could not create project"
            )
        }
    }

    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent
                className="sm:max-w-lg max-h-[90vh] overflow-y-auto"
                showCloseButton
            >
                <DialogHeader>
                    <DialogTitle>
                        {isEdit ? "Edit project" : "New project"}
                    </DialogTitle>
                </DialogHeader>
                <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
                    <div>
                        <label className="text-[10px] font-bold text-gray-400 uppercase tracking-widest mb-1.5 block">
                            Name <span className="text-red-500">*</span>
                        </label>
                        <Input
                            {...register("name")}
                            placeholder="Project name"
                            className="rounded-xl"
                        />
                        {errors.name && (
                            <p className="text-[11px] text-red-500 mt-1">{errors.name.message}</p>
                        )}
                    </div>
                    
                    <div>
                        <label className="text-[10px] font-bold text-gray-400 uppercase tracking-widest mb-1.5 block">
                            Status
                        </label>
                        <Controller
                            name="status"
                            control={control}
                            render={({ field }) => (
                                <ReactSelect
                                    value={field.value}
                                    onValueChange={field.onChange}
                                    options={statusOptions}
                                    triggerClassName="rounded-xl w-full min-h-10"
                                    contentClassName="rounded-xl"
                                />
                            )}
                        />
                    </div>
                    <div className="grid grid-cols-2 gap-3">
                        <div>
                            <label className="text-[10px] font-bold text-gray-400 uppercase tracking-widest mb-1.5 block">
                                Start date
                            </label>
                            <Controller
                                name="startDate"
                                control={control}
                                render={({ field }) => (
                                    <DatePicker
                                        value={field.value || ""}
                                        onChange={(date) => field.onChange(date || "")}
                                        placeholder="Pick start date"
                                        className="w-full"
                                    />
                                )}
                            />
                        </div>
                        <div>
                            <label className="text-[10px] font-bold text-gray-400 uppercase tracking-widest mb-1.5 block">
                                End date
                            </label>
                            <Controller
                                name="endDate"
                                control={control}
                                render={({ field }) => (
                                    <DatePicker
                                        value={field.value || ""}
                                        onChange={(date) => field.onChange(date || "")}
                                        placeholder="Pick end date"
                                        className="w-full"
                                    />
                                )}
                            />
                            {errors.endDate && (
                                <p className="text-[11px] text-red-500 mt-1">{errors.endDate.message}</p>
                            )}
                        </div>
                    </div>
                    <div>
                        <label className="text-[10px] font-bold text-gray-400 uppercase tracking-widest mb-1.5 block">
                            Budget (USD)
                        </label>
                        <Input
                            type="number"
                            {...register("budgetValue")}
                            placeholder="Optional"
                            className="rounded-xl"
                        />
                        {errors.budgetValue && (
                            <p className="text-[11px] text-red-500 mt-1">{errors.budgetValue.message}</p>
                        )}
                    </div>
                    <div>
                        <label className="text-[10px] font-bold text-gray-400 uppercase tracking-widest mb-1.5 block">
                            Linked lead
                        </label>
                        <Controller
                            name="leadId"
                            control={control}
                            render={({ field }) => (
                                <ReactSelect
                                    value={field.value ?? ""}
                                    onValueChange={field.onChange}
                                    options={leadOptions}
                                    placeholder="Optional"
                                    allowEmpty
                                    emptyOptionLabel="No linked lead"
                                    triggerClassName="rounded-xl w-full min-h-10"
                                    contentClassName="rounded-xl"
                                />
                            )}
                        />
                    </div>
                    <div>
                        <label className="text-[10px] font-bold text-gray-400 uppercase tracking-widest mb-1.5 block">
                            Owner
                        </label>
                        <Controller
                            name="ownerId"
                            control={control}
                            render={({ field }) => (
                                <ReactSelect
                                    value={field.value ?? ""}
                                    onValueChange={field.onChange}
                                    options={ownerOptions}
                                    placeholder="Optional"
                                    allowEmpty
                                    emptyOptionLabel="Unassigned"
                                    triggerClassName="rounded-xl w-full min-h-10"
                                    contentClassName="rounded-xl"
                                />
                            )}
                        />
                    </div>

                    <div>
                        <label className="text-[10px] font-bold text-gray-400 uppercase tracking-widest mb-1.5 block">
                            Description <span className="text-red-500">*</span>
                        </label>
                        <Textarea
                            {...register("description")}
                            placeholder="Please provide a detailed description (min 100 characters)..."
                            rows={4}
                            className="rounded-xl resize-none"
                        />
                        {errors.description && (
                            <p className="text-[11px] text-red-500 mt-1">{errors.description.message}</p>
                        )}
                    </div>

                    <DialogFooter className="gap-2 sm:gap-3 pt-2">
                        <Button
                            type="button"
                            variant="outline"
                            className="rounded-xl"
                            onClick={() => onOpenChange(false)}
                        >
                            Cancel
                        </Button>
                        <Button
                            type="submit"
                            disabled={saving}
                            className="rounded-xl bg-[#6C63FF] hover:bg-[#5a52e6]"
                        >
                            {saving ? (
                                <Loader2 className="size-4 animate-spin" />
                            ) : isEdit ? (
                                "Save"
                            ) : (
                                "Create"
                            )}
                        </Button>
                    </DialogFooter>
                </form>
            </DialogContent>
        </Dialog>
    )
}
