import Form from '@/components/form/Form';
import FormField from '@/components/form/FormField';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { type User } from '@/types';
import { yupResolver } from '@hookform/resolvers/yup';
import { router, usePage } from '@inertiajs/react';
import { Dot, Edit3, Loader2, Lock, UserPlus } from 'lucide-react';
import { useEffect, useState } from 'react';
import { SubmitHandler, useFormContext } from 'react-hook-form';
import { toast } from 'sonner';
import * as yup from 'yup';
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '../ui/accordion';

interface Role {
    id: number;
    name: string;
    slug: string;
    primary_access_level: number;
    access_level_label: string;
    access_level_scope: string;
}

interface Branch {
    id: number;
    title: string;
}

interface UserModalProps {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    user?: User | null;
    roles: Role[];
    branches?: Branch[];
    userType?: number;
    entityLabel?: string;
    onSuccess?: () => void;
}

const ACCESS_LEVEL_COLORS: Record<number, string> = {
    1: 'bg-blue-100 text-blue-800 border-blue-300',
    2: 'bg-amber-100 text-amber-800 border-amber-300',
    3: 'bg-purple-100 text-purple-800 border-purple-300',
};

function RoleAccessSection({ roles, branches }: { roles: Role[]; branches: Branch[] }) {
    const { watch, setValue } = useFormContext();
    const roleId = watch('role_id');

    const selectedRole = roles.find((r) => r.id === Number(roleId));
    const accessLevel = selectedRole?.primary_access_level ?? null;
    const accessLabel = selectedRole?.access_level_label ?? '';
    const isBranch = accessLevel === 2;

    // Clear branch_ids when role changes away from branch access
    useEffect(() => {
        if (!isBranch) {
            setValue('branch_ids', []);
        }
    }, [isBranch, setValue]);

    const roleOptions = roles.map((r) => ({ value: String(r.id), label: r.name }));

    const branchOptions = branches.map((b) => ({ value: String(b.id), label: b.title }));

    return (
        <>
            <div className="mb-5 gap-4 flex items-center">
                <div className="w-full">

                    <FormField
                        type="select"
                        name="role_id"
                        label="Role"
                        placeholder="Select role (optional)"
                        options={roleOptions}
                        className='w-full'
                    />
                </div>
                {accessLevel &&
                    <div className="flex flex-col justify-end gap-1 w-72">
                        <label className="text-sm font-medium text-gray-700">Role Access Level</label>
                        <div className="flex h-10 items-center">
                            {accessLevel ? (
                                <Badge className={`border px-3 h-9 w-full text-sm font-medium ${ACCESS_LEVEL_COLORS[accessLevel] ?? ''}`}>
                                    {accessLabel}
                                </Badge>
                            ) : (
                                <span className="text-sm text-gray-400">— select a role —</span>
                            )}
                        </div>
                    </div>
                }
            </div>

            {isBranch && (
                <div className="mb-5">
                    <FormField
                        type="multiselect"
                        name="branch_ids"
                        label="Branches"
                        placeholder="Select branches"
                        options={branchOptions}
                    />
                </div>
            )}
        </>
    );
}

const createSchema = (isEditing: boolean) => {
    const baseSchema = {
        first_name: yup.string().required('First name is required').min(2, 'First name must be at least 2 characters'),
        last_name: yup.string().required('Last name is required').min(2, 'Last name must be at least 2 characters'),
        uid: yup.string().optional(),
        email: yup.string().email('Invalid email address').required('Email is required'),
        phone: yup.string().optional(),
        address: yup.string().optional(),
        role_id: yup.number().nullable().optional(),
        branch_ids: yup.array().of(yup.string()).optional(),
    };

    if (!isEditing) {
        return yup.object({
            ...baseSchema,
            password: yup.string().required('Password is required').min(8, 'Password must be at least 8 characters'),
            password_confirmation: yup
                .string()
                .required('Password confirmation is required')
                .oneOf([yup.ref('password')], 'Passwords must match'),
        });
    }

    return yup
        .object({
            ...baseSchema,
            password: yup.string().optional(),
            password_confirmation: yup.string().optional(),
        })
        .test('passwords-match', 'Passwords must match', function (values) {
            const { password, password_confirmation } = values;
            if (password && password.length > 0) {
                if (!password_confirmation) {
                    return this.createError({
                        path: 'password_confirmation',
                        message: 'Password confirmation is required when password is provided',
                    });
                }
                if (password !== password_confirmation) {
                    return this.createError({ path: 'password_confirmation', message: 'Passwords must match' });
                }
                if (password.length < 8) {
                    return this.createError({ path: 'password', message: 'Password must be at least 8 characters' });
                }
            }
            return true;
        });
};

export function UserModal({ open, onOpenChange, user, roles, branches = [], userType = 1, entityLabel = 'User', onSuccess }: UserModalProps) {
    const isAdmin = user?.is_admin;
    const [isSubmitting, setIsSubmitting] = useState(false);
    const isEditing = Boolean(user);
    const page = usePage<any>();
    const current_user_role = page.props.auth.user.current_role_name;

    const getFirstName = () => {
        if (user?.first_name) return user.first_name;
        if (user?.name) return user.name.split(' ')[0] || '';
        return '';
    };

    const getLastName = () => {
        if (user?.last_name) return user.last_name;
        if (user?.name) return user.name.split(' ').slice(1).join(' ') || '';
        return '';
    };

    const defaultValues = {
        first_name: getFirstName(),
        last_name: getLastName(),
        uid: user?.uid || '',
        email: user?.email || '',
        phone: user?.phone || '',
        address: user?.address || '',
        password: '',
        password_confirmation: '',
        role_id: (user as any)?.role_id ?? null,
        branch_ids: (user as any)?.branch_ids?.map(String) ?? [],
    };

    const handleSubmit: SubmitHandler<any> = async (data) => {
        setIsSubmitting(true);

        const submitData: any = { ...data };

        if (submitData.first_name && submitData.last_name) {
            submitData.name = `${submitData.first_name} ${submitData.last_name}`;
        }

        submitData.type = isEditing ? (user?.type ?? userType) : userType;

        // Convert role_id and branch_ids to proper types for backend
        submitData.role_id = submitData.role_id ? Number(submitData.role_id) : null;
        submitData.branch_ids = (submitData.branch_ids ?? []).map(Number).filter(Boolean);

        if (isEditing && !submitData.password) {
            delete submitData.password;
            delete submitData.password_confirmation;
        }

        if (isEditing) {
            submitData._method = 'put';
        }

        try {
            const url = isEditing ? route('users.update', user!.uid) : route('users.store');
            router.post(url, submitData, {
                onSuccess: () => {
                    toast.success(isEditing ? `${entityLabel} updated successfully!` : `${entityLabel} created successfully!`);
                    onOpenChange(false);
                    onSuccess?.();
                },
                onError: (errors) => {
                    console.error('Form submission errors:', errors);
                    toast.error('Something went wrong. Please try again.');
                },
                onFinish: () => {
                    setIsSubmitting(false);
                },
            });
        } catch (error) {
            console.error('Submission error:', error);
            toast.error('Something went wrong. Please try again.');
            setIsSubmitting(false);
        }
    };

    const modalTitle = isEditing ? `Edit ${entityLabel}` : `Add New ${entityLabel}`;
    const modalDescription = isEditing
        ? `Update ${entityLabel.toLowerCase()} account details and permissions`
        : `Create new ${entityLabel.toLowerCase()} here. Click save when you're done.`;
    const IconComponent = isEditing ? Edit3 : UserPlus;

    useEffect(() => {
        if (!open) setIsSubmitting(false);
    }, [open]);

    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent className="max-h-[95vh] w-[95vw] max-w-4xl overflow-y-auto sm:w-[90vw] md:max-w-3xl">
                <DialogHeader className="gap-0 pb-4">
                    <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between">
                        <div className="flex items-center gap-3">
                            <IconComponent className="h-6 w-6" />
                            <div>
                                <DialogTitle className="text-lg sm:text-xl">{modalTitle}</DialogTitle>
                            </div>
                        </div>
                    </div>
                    <DialogDescription className="text-sm text-text-gray sm:text-base">{modalDescription}</DialogDescription>
                </DialogHeader>

                <div className="space-y-4 rounded-lg border px-2 py-4 sm:px-4 md:px-6">
                    <Form
                        submitHandler={handleSubmit}
                        resolver={yupResolver(createSchema(isEditing))}
                        defaultValues={defaultValues}
                        key={user?.id || 'create'}
                        externalErrors={(page.props as any)?.errors}
                    >
                        {/* Personal Details */}
                        <div className="mb-5 grid gap-4 sm:grid-cols-1 md:grid-cols-2">
                            <FormField type="text" name="first_name" label="First Name" placeholder="John" required />
                            <FormField type="text" name="last_name" label="Last Name" placeholder="Doe" required />
                        </div>

                        {/* Email */}
                        <div className="mb-5 grid gap-4 sm:grid-cols-1 md:grid-cols-2">
                            <FormField
                                type="email"
                                name="email"
                                label="Email"
                                placeholder="john.doe@gmail.com"
                                required
                                disabled={isEditing && current_user_role !== 'admin'}
                            />
                            <FormField type="text" name="phone" label="Phone Number" placeholder="+123456789" />
                        </div>

                        {/* Role + Access Level (skip for super-admin) */}
                        {!isAdmin && <RoleAccessSection roles={roles} branches={branches} />}

                        {/* Address */}
                        <div className="mb-5">
                            <FormField type="text" name="address" label="Address" placeholder="Address" />
                        </div>

                        {/* Password */}
                        {isEditing ? (
                            <Accordion type="single" collapsible className="mb-5">
                                <AccordionItem value="password" className="rounded-lg border px-4">
                                    <AccordionTrigger className="hover:no-underline">
                                        <div className="flex items-center gap-2">
                                            <Lock className="h-4 w-4" />
                                            <span>Change Password</span>
                                        </div>
                                    </AccordionTrigger>
                                    <AccordionContent className="pt-4">
                                        <div className="grid gap-4 sm:grid-cols-1 md:grid-cols-2">
                                            <FormField
                                                type="password"
                                                name="password"
                                                label="New Password"
                                                placeholder="Enter new password"
                                                description="Leave empty to keep current password"
                                                required={false}
                                            />
                                            <FormField
                                                type="password"
                                                name="password_confirmation"
                                                label="Confirm New Password"
                                                placeholder="Confirm new password"
                                                required={false}
                                            />
                                        </div>
                                    </AccordionContent>
                                </AccordionItem>
                            </Accordion>
                        ) : (
                            <div className="mb-5 grid gap-4 sm:grid-cols-1 md:grid-cols-2">
                                <FormField type="password" name="password" label="Password" placeholder="Enter password" required />
                                <FormField type="password" name="password_confirmation" label="Confirm Password" placeholder="Confirm password" required />
                            </div>
                        )}

                        {/* Actions */}
                        <div className="flex flex-col-reverse gap-3 sm:flex-row sm:justify-end">
                            <Button type="submit" disabled={isSubmitting} className="w-full bg-success hover:bg-brand-800 sm:w-auto">
                                {isSubmitting ? (
                                    <>
                                        <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                                        {isEditing ? `Updating ${entityLabel}...` : `Creating ${entityLabel}...`}
                                    </>
                                ) : (
                                    <>Save Changes</>
                                )}
                            </Button>
                        </div>
                    </Form>
                </div>
            </DialogContent>
        </Dialog>
    );
}
