'use client';
import { useMemo } from 'react'
import Image from 'next/image'
import Dialog from '@/components/ui/Dialog'
import { Form, FormItem } from '@/components/ui/Form'
import Button from '@/components/ui/Button'
import Input from '@/components/ui/Input'
import Select from '@/components/ui/Select'
import DatePicker from '@/components/ui/DatePicker/DatePicker'
import SelectInputWithPrefix from '@/components/shared/SelectInputWithPrefix'
import SelectOptionWithPrefix from '@/components/shared/SelectOptionWithPrefix'
import IconFrame from '@/components/shared/IconFrame'
import { useScrumboardStore } from '../_store/useScrumboardStore'
import { priorityMap, tagsMap } from '../utils'
import { LiTag, LiCross } from '@/icons'
import classNames from '@/utils/classNames'
import sleep from '@/utils/sleep'
import dayjs from 'dayjs'
import { useForm, Controller } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'

const validationSchema = z.object({
    subject: z.string().min(1, 'Please input subject!'),
    description: z.string().min(1, 'Please input description!'),
    priority: z.string().min(1, 'Please select priority!'),
    dueDate: z.string().min(1, 'Please select due date!'),
    tags: z.array(z.string()).nonempty('Select at least one tag!'),
    assignee: z.string().min(1, 'Please select one assignee!'),
})

const AddTaskDialog = () => {
    const selectedColumn = useScrumboardStore((s) => s.selectedColumn)
    const addTaskDialogOpen = useScrumboardStore((s) => s.addTaskDialogOpen)
    const setAddTaskDialogOpen = useScrumboardStore((s) => s.setAddTaskDialogOpen)
    const setSelectedColumn = useScrumboardStore((s) => s.setSelectedColumn)
    const projectMeta = useScrumboardStore((s) => s.projectMeta)
    const setTasks = useScrumboardStore((s) => s.setTasks)

    const {
        handleSubmit,
        reset,
        formState: { errors, isSubmitting },
        control,
    } = useForm({
        defaultValues: {
            subject: '',
            description: '',
            priority: '',
            dueDate: '',
            tags: [],
            assignee: '',
        },
        resolver: zodResolver(validationSchema),
    })

    const handleClose = async () => {
        setAddTaskDialogOpen(false)
        await sleep(200)
        setSelectedColumn('')
        reset()
    }

    const priorityOptions = useMemo(() =>
        Object.entries(priorityMap).map(([key]) => (({
            value: key,
            label: key,
        }))), [])

    const tagOptions = useMemo(() =>
        Object.entries(tagsMap).map(([key]) => (({
            value: key,
            label: key,
        }))), [])

    const assigneeOptions = useMemo(() =>
        projectMeta?.allMembers.map((member) => (({
            label: member.name,
            value: member.id,
            img: member.img,
        }))) || [], [projectMeta])

    const handleFormSubmit = async (values) => {
        await sleep(500)
        setTasks((data) => [
            {
                id: Date.now().toString(),
                subject: values.subject,
                columnId: selectedColumn,
                description: values.description,
                cover: '',
                members:
                    projectMeta?.allMembers.filter((member) => member.id === values.assignee) || [],
                tags: values.tags,
                priority: values.priority,
                attachmentCount: 0,
                taskCount: 0,
                commentCount: 0,
                dueDate: values.dueDate,
            },
            ...data,
        ])
        handleClose()
    }

    return (
        <Dialog
            isOpen={addTaskDialogOpen}
            onClose={handleClose}
            closable={false}
            className="p-0">
            <div
                className="border-b border-gray-200 dark:border-gray-700 p-4 flex justify-between gap-2">
                <div className="flex items-center gap-4">
                    <IconFrame variant="thick">
                        <LiTag className="text-xl heading-text" />
                    </IconFrame>
                    <div>
                        <h5>Add new ticket</h5>
                        <p className="pr-12 hidden sm:block">
                            Add a new ticket to the selected column
                        </p>
                    </div>
                </div>
                <Button
                    size="sm"
                    variant="subtle"
                    type="button"
                    icon={<LiCross className="text-2xl" />}
                    onClick={handleClose} />
            </div>
            <div className="p-4">
                <Form onSubmit={handleSubmit(handleFormSubmit)}>
                    <FormItem
                        label="Subject"
                        invalid={Boolean(errors.subject)}
                        errorMessage={errors.subject?.message}>
                        <Controller
                            name="subject"
                            control={control}
                            render={({ field }) => (
                                <Input placeholder="Enter Subject" {...field} />
                            )} />
                    </FormItem>
                    <FormItem
                        label="Description"
                        invalid={Boolean(errors.description)}
                        errorMessage={errors.description?.message}>
                        <Controller
                            name="description"
                            control={control}
                            render={({ field }) => (
                                <Input placeholder="Enter Description" {...field} textArea />
                            )} />
                    </FormItem>
                    <FormItem
                        label="Priority"
                        invalid={Boolean(errors.priority)}
                        errorMessage={errors.priority?.message}>
                        <Controller
                            name="priority"
                            control={control}
                            render={({ field }) => (
                                <Select
                                    options={priorityOptions}
                                    value={priorityOptions.find((option) =>
                                        option.value === field.value)}
                                    onChange={(option) =>
                                        field.onChange(option.value)
                                    }
                                    placeholder="Select priority"
                                    customInputDisplay={(selectedItem) => (
                                        <SelectInputWithPrefix
                                            label={selectedItem?.label}
                                            prefix={
                                                selectedItem && (
                                                    <span
                                                        className={classNames('h-3.5 w-3.5 rounded-xs', priorityMap[
                                                            selectedItem
                                                                .label
                                                        ].color)}></span>
                                                )
                                            } />
                                    )}
                                    customOption={({
                                        option,
                                        selected,
                                        CheckIcon,
                                    }) => (
                                        <SelectOptionWithPrefix
                                            selected={selected}
                                            checkIcon={CheckIcon}
                                            label={option?.label}
                                            prefix={
                                                <span
                                                    className={classNames('h-3.5 w-3.5 rounded-xs', priorityMap[
                                                        option.label
                                                    ].color)}></span>
                                            } />
                                    )} />
                            )} />
                    </FormItem>
                    <FormItem
                        label="Due Date"
                        invalid={Boolean(errors.dueDate)}
                        errorMessage={errors.dueDate?.message}>
                        <Controller
                            name="dueDate"
                            control={control}
                            render={({ field }) => (
                                <DatePicker
                                    placeholder="Select Due Date"
                                    value={
                                        field.value
                                            ? dayjs(field.value).toDate()
                                            : null
                                    }
                                    onChange={(value) =>
                                        field.onChange(dayjs(value).toISOString())
                                    }
                                    clearable={false} />
                            )} />
                    </FormItem>
                    <FormItem
                        label="Assignee"
                        invalid={Boolean(errors.assignee)}
                        errorMessage={errors.assignee?.message}>
                        <Controller
                            name="assignee"
                            control={control}
                            render={({ field }) => (
                                <Select
                                    options={assigneeOptions}
                                    onChange={(option) =>
                                        field.onChange(option?.value)
                                    }
                                    value={assigneeOptions.find((option) =>
                                        option.value === field.value)}
                                    placeholder="Select Assignee"
                                    customInputDisplay={(selectedItem) => (
                                        <SelectInputWithPrefix
                                            label={selectedItem?.label}
                                            showPrefix={Boolean(selectedItem?.value)}
                                            prefix={
                                                selectedItem && (
                                                    <Image
                                                        src={selectedItem.img}
                                                        className="rounded-full"
                                                        alt={
                                                            selectedItem?.label
                                                        }
                                                        width={20}
                                                        height={20} />
                                                )
                                            } />
                                    )}
                                    customOption={({
                                        option,
                                        selected,
                                        CheckIcon,
                                    }) => (
                                        <SelectOptionWithPrefix
                                            selected={selected}
                                            checkIcon={CheckIcon}
                                            label={option?.label}
                                            prefix={
                                                <Image
                                                    src={option?.img}
                                                    className="rounded-full"
                                                    alt={option?.label}
                                                    width={20}
                                                    height={20} />
                                            } />
                                    )} />
                            )} />
                    </FormItem>
                    <FormItem
                        label="Tags"
                        invalid={Boolean(errors.tags)}
                        errorMessage={errors.tags?.message}>
                        <Controller
                            name="tags"
                            control={control}
                            render={({ field }) => (
                                <Select.Multi
                                    options={tagOptions}
                                    value={tagOptions.filter((option) =>
                                        field.value.includes(option.value))}
                                    onChange={(options) =>
                                        field.onChange(options.map((option) => option.value))
                                    }
                                    placeholder="Select tags" />
                            )} />
                    </FormItem>
                    <div className="mt-4 flex justify-end gap-2">
                        <Button type="button" onClick={handleClose}>
                            Cancel
                        </Button>
                        <Button variant="solid" loading={isSubmitting} type="submit">
                            Add Ticket
                        </Button>
                    </div>
                </Form>
            </div>
        </Dialog>
    );
}

export default AddTaskDialog
