import Form from '@admin/components/form/Form';
import FormField from '@admin/components/form/FormField';
import { Button } from '@admin/components/ui/button';
import { zodResolver } from '@hookform/resolvers/zod';
import { Plus } from 'lucide-react';
import { useFormContext } from 'react-hook-form';
import { z } from 'zod';

export type TaskFormValues = z.infer<typeof TaskFormSchema>;

export type NormalizedTaskPayload = {
    title: string;
    description: string;
    status: number;
    assigned_user_ids?: number[];
    due_date?: string;
    tags?: string[];
    priority?: string;
    relation_type?: string;
    contactId?: string;
};

interface TaskFormProps {
    mode: 'add' | 'edit';
    initialTask?: any;
    onSubmitTask: (payload: NormalizedTaskPayload) => void;
    onCancel?: () => void;
    className?: string;
    users?: Array<{ label: string; value: string }>;
    availableTags?: Array<{ label: string; value: string; color?: string }>;
    relationType?: string;
    contactId?: string;
}

const TaskFormSchema = z.object({
    title: z.string().min(3, 'Title must be at least 3 characters'),
    status: z.coerce.number().optional(),
    assignType: z.enum(['Self', 'Others']).optional(),
    tags: z.array(z.string()).optional(),
    description: z.string().max(1000).optional().or(z.literal('')),
    due_date: z.string().optional().or(z.literal('')),
    assigned_user_ids: z.array(z.union([z.string(), z.number(), z.coerce.number()])).optional(),
    priority: z.coerce.number().int().min(1).max(3).optional(),
});

export default function TaskForm({
    mode,
    initialTask,
    onSubmitTask,
    onCancel,
    className,
    users = [],
    availableTags = [],
    relationType,
    contactId,
}: TaskFormProps) {
    // Normalize initialTask (task model) to form field names
    const mappedInitial = initialTask
        ? {
              title: (initialTask.title as string) || (initialTask.name as string) || '',
              description: initialTask.description || '',
              status: Number(initialTask.status) || 20,
              // Convert tag objects to tag names for the form
              tags: Array.isArray(initialTask.tags) ? initialTask.tags.map((tag: any) => (typeof tag === 'string' ? tag : tag.name)) : [],
              assignType: initialTask.assigned_user_ids && initialTask.assigned_user_ids.length > 0 ? 'Others' : ('Self' as 'Self' | 'Others'),
              // Convert assigned_user_ids to strings for multiselect compatibility
              assigned_user_ids: (initialTask.assigned_user_ids || []).map((id: number) => String(id)),
              due_date: initialTask.due_date || '',
              contactId: contactId,
              priority: Number(initialTask.priority) || 2, // Default to medium priority if not set
          }
        : {};

    const defaultValues = {
        title: '',
        description: '',
        status: 20, // Todo
        tags: [],
        assignType: 'Self',
        assigned_user_ids: [],
        due_date: '',
        priority: 2, // Default to medium priority
        relation_type: relationType || '',
        contactId: contactId,
        ...mappedInitial,
    };

    const resolver = zodResolver(TaskFormSchema);

    const handleSubmit = async (values: TaskFormValues) => {
        // Map priority number to string for the API
        const priorityMap: Record<number, string> = {
            1: 'low',
            2: 'medium',
            3: 'high',
        };

        // Ensure assigned_user_ids is an array of numbers or empty
        let assignedUserIds: number[] = [];
        if (values.assignType === 'Others' && values.assigned_user_ids && Array.isArray(values.assigned_user_ids)) {
            assignedUserIds = values.assigned_user_ids
                .map((id) => (typeof id === 'string' ? parseInt(id, 10) : Number(id)))
                .filter((id) => !isNaN(id));
        }

        // Use the selected priority from the form
        const payload: NormalizedTaskPayload = {
            title: values.title || '',
            description: values.description || '',
            status: Number(values.status) || 20,
            assigned_user_ids: assignedUserIds,
            tags: values.tags || [],
            due_date: values.due_date || undefined,
            priority: values.priority ? priorityMap[Number(values.priority)] : 'medium',
            relation_type: relationType,
            contactId: contactId,
        };
        onSubmitTask(payload);
    };

    return (
        <div className={['space-y-6 p-2', className].filter(Boolean).join(' ')}>
            <Form submitHandler={handleSubmit} defaultValues={defaultValues} formClassNames="space-y-6" resolver={resolver}>
                <FormField name="title" label="Title" type="text" placeholder="eg: Forward Tactics Project Design" required />

                <FormField name="description" label="Description (optional)" type="textarea" />
                {/* Assign To (Self / Others) */}
                <FormField name="assignType" label="Assign To" type="radio" options={['Self', 'Others']} orientation="horizontal" />

                {/* If Others is selected, allow selecting users */}
                <AssignPeopleWatcher users={users} />

                <FormField
                    name="tags"
                    label="Tags"
                    type="multiselect"
                    options={
                        availableTags.length > 0
                            ? availableTags
                            : [
                                  { value: 'Work', label: 'Work' },
                                  { value: 'Personal', label: 'Personal' },
                                  { value: 'Important', label: 'Important' },
                                  { value: 'Urgent', label: 'Urgent' },
                              ]
                    }
                    placeholder="Select tags"
                />

                {/* Due Date and Status side-by-side to match design */}
                <div className="grid grid-cols-2 gap-4">
                    <FormField name="due_date" label="Due Date" type="date" />
                    <FormField
                        name="status"
                        label="Status"
                        type="select"
                        options={[
                            { value: 20, label: 'Todo' },
                            { value: 5, label: 'Completed' },
                            { value: 11, label: 'Archived' },
                            { value: 18, label: 'Important' },
                        ]}
                    />
                </div>

                {/* Priority field */}
                <FormField
                    name="priority"
                    label="Priority"
                    type="select"
                    options={[
                        { value: 1, label: 'Low' },
                        { value: 2, label: 'Medium' },
                        { value: 3, label: 'High' },
                    ]}
                />

                <div className="flex justify-end gap-3">
                    <Button variant="outline" onClick={onCancel} type="button">
                        Cancel
                    </Button>
                    <Button className="hover:bg-success-800 bg-success text-white" type="submit">
                        <Plus className="h-4 w-4" />
                        {mode === 'add' ? 'Add Task' : 'Save'}
                    </Button>
                </div>
            </Form>
        </div>
    );
}

// Small helper component to show a user selector when assignType === 'Others'
function AssignPeopleWatcher({ users }: { users: Array<{ label: string; value: string }> }) {
    const { watch } = useFormContext();
    const assignType = watch('assignType');

    if (assignType !== 'Others') return null;

    return <FormField name="assigned_user_ids" label="Assign Users" type="multiselect" options={users} placeholder="Select users" required />;
}
