import Form from '@/components/form/Form';
import FormField from '@/components/form/FormField';
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { yupResolver } from '@hookform/resolvers/yup';
import { Link, router } from '@inertiajs/react';
import { ArrowLeft, Edit3, Loader2, Lock, UserPlus } from 'lucide-react';
import { useState } from 'react';
import { SubmitHandler } from 'react-hook-form';
import * as yup from 'yup';

interface Role {
    id: number;
    name: string;
}

interface User {
    id?: number;
    name: string;
    email: string;
    phone?: string;
    role?: string[];
}

interface UserFormProps {
    user?: User;
    roles: Role[];
    isEditing?: boolean;
    roleScopesMap?: Record<string, Record<string, string>>;
}

const SCOPE_BADGE_COLORS: Record<string, string> = {
    global: 'bg-green-100 text-green-800 border-green-300',
    branch: 'bg-blue-100 text-blue-800 border-blue-300',
    local:  'bg-yellow-100 text-yellow-800 border-yellow-300',
};

function ScopeBadges({ roleIds, roleScopesMap }: { roleIds: string[]; roleScopesMap: Record<string, Record<string, string>> }) {
    if (!roleIds.length) return null;

    const merged: Record<string, string> = {};
    for (const id of roleIds) {
        const scopes = roleScopesMap[id];
        if (scopes) {
            Object.assign(merged, scopes);
        }
    }

    const entries = Object.entries(merged);
    if (!entries.length) return null;

    return (
        <div className="mt-2 flex flex-wrap gap-1">
            {entries.map(([mod, scope]) => (
                <span key={mod} className={`inline-flex items-center rounded border px-2 py-0.5 text-xs font-medium ${SCOPE_BADGE_COLORS[scope] ?? 'bg-gray-100 text-gray-700 border-gray-300'}`}>
                    {mod}: {scope.charAt(0).toUpperCase() + scope.slice(1)}
                </span>
            ))}
        </div>
    );
}

// Create validation schema that adapts based on edit mode
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'),
        email: yup.string().email('Invalid email address').required('Email is required'),
        phone: yup.string().nullable().optional().matches(/^\+?[0-9\s-]{7,20}$/, { message: 'Invalid phone number', excludeEmptyString: true }),
        roles: yup.array().of(yup.string()).min(1, 'Please select at least one role'),
    };

    // Only require passwords for new users or when changing password during edit
    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'),
        });
    }

    // For editing, passwords are optional but must match if provided
    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 is provided, confirmation must also be provided and match
            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;
        });
};

const UserForm = ({ user, roles, isEditing = false, roleScopesMap = {} }: UserFormProps) => {
    const [isSubmitting, setIsSubmitting] = useState(false);
    const [selectedRoleIds, setSelectedRoleIds] = useState<string[]>([]);

    // Transform roles into options format
    const roleOptions = roles.map((role) => ({
        value: role.id.toString(),
        label: role.name,
    }));

    // Get user's current role IDs for editing
    const getUserRoleIds = () => {
        if (!user?.role) return [];
        return user.role
            .map((roleName) => {
                const roleObj = roles.find((r) => r.name.toLowerCase() === roleName.toLowerCase());
                return roleObj ? roleObj.id.toString() : null;
            })
            .filter(Boolean) as string[];
    };

    const nameParts = user?.name?.split(' ') ?? [];
    const defaultValues = {
        first_name: nameParts[0] ?? '',
        last_name: nameParts.slice(1).join(' ') ?? '',
        email: user?.email || '',
        phone: user?.phone || '',
        password: '',
        password_confirmation: '',
        roles: isEditing ? getUserRoleIds() : [],
    };

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

        // Remove empty password fields for editing
        const submitData = { ...data };
        if (isEditing && !submitData.password) {
            delete submitData.password;
            delete submitData.password_confirmation;
        }

        // Add method for editing
        if (isEditing) {
            submitData._method = 'put';
        }

        try {
            const url = isEditing ? route('users.update', user!.id) : route('users.store');
            router.post(url, submitData, {
                onSuccess: () => {
                    // Handle success (redirect will be handled by the backend)
                },
                onError: (errors) => {
                    console.error('Form submission errors:', errors);
                },
                onFinish: () => {
                    setIsSubmitting(false);
                },
            });
        } catch (error) {
            console.error('Submission error:', error);
            setIsSubmitting(false);
        }
    };

    const pageTitle = isEditing ? 'Edit User' : 'Create New User';
    const pageDescription = isEditing ? 'Update user account details and permissions' : 'Add a new user account with roles and permissions';
    const cardTitle = isEditing ? 'Edit User Information' : 'User Information';
    const cardDescription = isEditing ? 'Update the details for this user' : 'Fill in the details to create a new user';
    const submitButtonText = isEditing ? 'Update User' : 'Create User';
    const IconComponent = isEditing ? Edit3 : UserPlus;

    return (
        <div className="flex h-full flex-1 flex-col gap-6 p-6">
            <div className="mx-auto w-full max-w-2xl space-y-6">
                {/* Header Section */}
                <div className="flex items-center justify-between">
                    <div>
                        <h1 className="text-2xl font-bold text-gray-900">{pageTitle}</h1>
                        <p className="mt-1 text-sm text-gray-600">{pageDescription}</p>
                    </div>
                    <Button variant="outline" asChild>
                        <Link href={route('users.index')}>
                            <ArrowLeft className="mr-2 h-4 w-4" />
                            Back
                        </Link>
                    </Button>
                </div>

                {/* Form Card */}
                <Card className="shadow-sm">
                    <CardHeader className="pb-4">
                        <div className="flex items-center gap-3">
                            <div className="flex h-10 w-10 items-center justify-center rounded-lg bg-blue-100">
                                <IconComponent className="h-5 w-5 text-blue-600" />
                            </div>
                            <div>
                                <CardTitle className="text-lg">{cardTitle}</CardTitle>
                                <CardDescription>{cardDescription}</CardDescription>
                            </div>
                        </div>
                    </CardHeader>

                    <CardContent className="space-y-6">
                        <Form submitHandler={handleSubmit} resolver={yupResolver(createSchema(isEditing))} defaultValues={defaultValues}>
                            {/* Personal Details */}
                            <div className="mb-5 grid gap-4 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="Smith" required />
                            </div>
                            <div className="mb-5 grid gap-4 md:grid-cols-2">
                                <FormField type="email" name="email" label="Email Address" placeholder="john@company.com" required />
                                <FormField type="text" name="phone" label="Phone" placeholder="+1234567890" />
                            </div>

                            {/* Password Section */}
                            {isEditing ? (
                                /* Password change accordion for editing */
                                <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 md:grid-cols-2">
                                                <FormField
                                                    type="password"
                                                    name="password"
                                                    label="New Password"
                                                    placeholder="Enter new password"
                                                    description="Leave empty to keep current password"
                                                />
                                                <FormField
                                                    type="password"
                                                    name="password_confirmation"
                                                    label="Confirm New Password"
                                                    placeholder="Confirm new password"
                                                />
                                            </div>
                                        </AccordionContent>
                                    </AccordionItem>
                                </Accordion>
                            ) : (
                                /* Required password fields for creating */
                                <div className="mb-5 grid gap-4 md:grid-cols-2">
                                    <FormField
                                        type="password"
                                        name="password"
                                        label="Password"
                                        placeholder="Enter password"
                                        required
                                        description="Minimum 8 characters"
                                    />
                                    <FormField
                                        type="password"
                                        name="password_confirmation"
                                        label="Confirm Password"
                                        placeholder="Confirm password"
                                        required
                                    />
                                </div>
                            )}

                            {/* Roles */}
                            <div>
                                <FormField
                                    type="multiselect"
                                    name="roles"
                                    label="User Roles"
                                    placeholder="Select user roles"
                                    options={roleOptions}
                                    required
                                    description="Choose roles for this user"
                                    onChange={(val: string[]) => setSelectedRoleIds(val ?? [])}
                                />
                                {Object.keys(roleScopesMap).length > 0 && (
                                    <ScopeBadges roleIds={selectedRoleIds} roleScopesMap={roleScopesMap} />
                                )}
                            </div>

                            {/* Actions */}
                            <div className="flex justify-end gap-3 pt-4">
                                <Button variant="outline" type="button" disabled={isSubmitting} asChild>
                                    <Link href={route('users.index')}>Cancel</Link>
                                </Button>
                                <Button type="submit" disabled={isSubmitting}>
                                    {isSubmitting ? (
                                        <>
                                            <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                                            {isEditing ? 'Updating...' : 'Creating...'}
                                        </>
                                    ) : (
                                        <>
                                            <IconComponent className="mr-2 h-4 w-4" />
                                            {submitButtonText}
                                        </>
                                    )}
                                </Button>
                            </div>
                        </Form>
                    </CardContent>
                </Card>
            </div>
        </div>
    );
};

export default UserForm;
