'use client';

import { useState, useEffect } from 'react';
import { Input, TagInput, Modal, Badge } from '@zen/core/shared/components';
import { useToast } from '@zen/core/toast';

const UserEditModal = ({ userId, currentUserId, isOpen, onClose, onSaved }) => {
    const toast = useToast();
    const isSelf = userId && currentUserId && userId === currentUserId;

    const [userData, setUserData] = useState(null);
    const [loading, setLoading] = useState(false);
    const [saving, setSaving] = useState(false);

    const [formData, setFormData] = useState({ name: '', email: '', currentPassword: '', newPassword: '' });
    const [errors, setErrors] = useState({});
    const [sendingReset, setSendingReset] = useState(false);

    const [allRoles, setAllRoles] = useState([]);
    const [selectedRoleIds, setSelectedRoleIds] = useState([]);
    const [initialRoleIds, setInitialRoleIds] = useState([]);

    useEffect(() => {
        if (!isOpen || !userId) return;
        loadAll();
    }, [isOpen, userId]);

    const loadAll = async () => {
        try {
            setLoading(true);
            setErrors({});
            const [userRes, rolesRes, userRolesRes] = await Promise.all([
                fetch(`/zen/api/users/${userId}`, { credentials: 'include' }),
                fetch('/zen/api/roles', { credentials: 'include' }),
                fetch(`/zen/api/users/${userId}/roles`, { credentials: 'include' }),
            ]);
            const [userJson, rolesJson, userRolesJson] = await Promise.all([
                userRes.json(),
                rolesRes.json(),
                userRolesRes.json(),
            ]);

            if (userJson.user) {
                setUserData(userJson.user);
                setFormData({
                    name: userJson.user.name || '',
                    email: userJson.user.email || '',
                    currentPassword: '',
                    newPassword: '',
                });
            } else {
                toast.error(userJson.message || 'Utilisateur introuvable');
                onClose();
                return;
            }

            setAllRoles(rolesJson.roles || []);

            const ids = (userRolesJson.roles || []).map(r => r.id);
            setSelectedRoleIds(ids);
            setInitialRoleIds(ids);
        } catch {
            toast.error("Impossible de charger l'utilisateur");
            onClose();
        } finally {
            setLoading(false);
        }
    };

    const handleInputChange = (field, value) => {
        setFormData(prev => ({ ...prev, [field]: value }));
        if (errors[field]) setErrors(prev => ({ ...prev, [field]: null }));
    };

    const handleSendPasswordReset = async () => {
        setSendingReset(true);
        try {
            const res = await fetch(`/zen/api/users/${userId}/send-password-reset`, {
                method: 'POST',
                credentials: 'include',
            });
            const data = await res.json();
            if (!res.ok) throw new Error(data.error || data.message || 'Impossible d\'envoyer le lien');
            toast.success(data.message || 'Lien de réinitialisation envoyé');
        } catch {
            toast.error('Impossible d\'envoyer le lien de réinitialisation');
        } finally {
            setSendingReset(false);
        }
    };

    const emailChanged = userData && formData.email !== userData.email;

    const needsCurrentPassword = isSelf && (emailChanged || !!formData.newPassword);

    const validate = () => {
        const newErrors = {};
        if (!formData.name?.trim()) newErrors.name = 'Le nom est requis';
        if (needsCurrentPassword && !formData.currentPassword) newErrors.currentPassword = 'Le mot de passe actuel est requis';
        setErrors(newErrors);
        return Object.keys(newErrors).length === 0;
    };

    const handleSubmit = async () => {
        if (!validate()) return;
        try {
            setSaving(true);

            const userRes = await fetch(`/zen/api/users/${userId}`, {
                method: 'PUT',
                headers: { 'Content-Type': 'application/json' },
                credentials: 'include',
                body: JSON.stringify({
                    name: formData.name.trim(),
                }),
            });
            const userResData = await userRes.json();
            if (!userRes.ok) {
                toast.error(userResData.message || userResData.error || "Impossible de mettre à jour l'utilisateur");
                return;
            }

            const toAdd = selectedRoleIds.filter(id => !initialRoleIds.includes(id));
            const toRemove = initialRoleIds.filter(id => !selectedRoleIds.includes(id));

            await Promise.all(
                toAdd.map(roleId =>
                    fetch(`/zen/api/users/${userId}/roles`, {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        credentials: 'include',
                        body: JSON.stringify({ roleId }),
                    })
                )
            );

            const removeResults = await Promise.all(
                toRemove.map(roleId =>
                    fetch(`/zen/api/users/${userId}/roles/${roleId}`, {
                        method: 'DELETE',
                        credentials: 'include',
                    }).then(async res => ({ res, data: await res.json() }))
                )
            );

            const failedRemove = removeResults.find(({ res }) => !res.ok);
            if (failedRemove) {
                toast.error(failedRemove.data?.message || failedRemove.data?.error || 'Impossible de retirer ce rôle');
                onSaved?.();
                onClose();
                return;
            }

            if (emailChanged) {
                if (isSelf) {
                    const emailRes = await fetch('/zen/api/users/profile/email', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        credentials: 'include',
                        body: JSON.stringify({ newEmail: formData.email.trim(), password: formData.currentPassword }),
                    });
                    const emailData = await emailRes.json();
                    if (!emailRes.ok) {
                        toast.error(emailData.error || emailData.message || 'Impossible de changer le courriel');
                        onSaved?.();
                        onClose();
                        return;
                    }
                    toast.success('Utilisateur mis à jour');
                    toast.info(emailData.message || 'Un courriel de confirmation a été envoyé');
                } else {
                    const emailRes = await fetch(`/zen/api/users/${userId}/email`, {
                        method: 'PUT',
                        headers: { 'Content-Type': 'application/json' },
                        credentials: 'include',
                        body: JSON.stringify({ newEmail: formData.email.trim() }),
                    });
                    const emailData = await emailRes.json();
                    if (!emailRes.ok) {
                        toast.error(emailData.error || emailData.message || 'Impossible de changer le courriel');
                        onSaved?.();
                        onClose();
                        return;
                    }
                    toast.success('Utilisateur mis à jour');
                }
            } else {
                toast.success('Utilisateur mis à jour');
            }

            if (formData.newPassword) {
                const pwdUrl = isSelf ? '/zen/api/users/profile/password' : `/zen/api/users/${userId}/password`;
                const pwdMethod = isSelf ? 'POST' : 'PUT';
                const pwdBody = isSelf
                    ? { currentPassword: formData.currentPassword, newPassword: formData.newPassword }
                    : { newPassword: formData.newPassword };
                const pwdRes = await fetch(pwdUrl, {
                    method: pwdMethod,
                    headers: { 'Content-Type': 'application/json' },
                    credentials: 'include',
                    body: JSON.stringify(pwdBody),
                });
                const pwdData = await pwdRes.json();
                if (!pwdRes.ok) {
                    toast.error(pwdData.error || pwdData.message || 'Impossible de changer le mot de passe');
                    onSaved?.();
                    onClose();
                    return;
                }
                toast.success('Mot de passe mis à jour');
            }

            onSaved?.();
            onClose();
        } catch {
            toast.error("Impossible de mettre à jour l'utilisateur");
        } finally {
            setSaving(false);
        }
    };

    const roleOptions = allRoles.map(r => ({
        value: r.id,
        label: r.name,
        color: r.color || '#6b7280',
        description: r.description || undefined,
    }));

    return (
        <Modal
            isOpen={isOpen}
            onClose={onClose}
            title="Modifier l'utilisateur"
            onSubmit={handleSubmit}
            submitLabel="Mettre à jour"
            loading={saving}
            disabled={loading}
            size="md"
        >
            {loading ? (
                <div className="flex flex-col gap-4 animate-pulse">
                    <div className="h-10 bg-neutral-100 dark:bg-neutral-800 rounded-lg" />
                    <div className="h-10 bg-neutral-100 dark:bg-neutral-800 rounded-lg" />
                    <div className="h-10 bg-neutral-100 dark:bg-neutral-800 rounded-lg" />
                </div>
            ) : (
                <div className="flex flex-col gap-4">
                    <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                        <Input
                            label="Nom *"
                            value={formData.name}
                            onChange={(value) => handleInputChange('name', value)}
                            placeholder="Nom de l'utilisateur"
                            error={errors.name}
                        />
                        <Input
                            label="Courriel"
                            type="email"
                            value={formData.email}
                            onChange={(value) => handleInputChange('email', value)}
                            placeholder="courriel@exemple.com"
                        />
                    </div>

                    <TagInput
                        label="Rôles attribués"
                        options={roleOptions}
                        value={selectedRoleIds}
                        onChange={setSelectedRoleIds}
                        placeholder="Rechercher un rôle..."
                        renderTag={(opt, onRemove) => (
                            <Badge key={opt.value} color={opt.color} dot onRemove={onRemove}>{opt.label}</Badge>
                        )}
                    />

                    <div className="flex flex-col gap-2">
                        <Input
                            label="Nouveau mot de passe (optionnel)"
                            type="password"
                            value={formData.newPassword}
                            onChange={(value) => handleInputChange('newPassword', value)}
                            placeholder="Laisser vide pour ne pas modifier"
                        />
                        <button
                            type="button"
                            onClick={handleSendPasswordReset}
                            disabled={sendingReset}
                            className="cursor-pointer text-left text-xs text-neutral-500 hover:text-neutral-800 dark:hover:text-neutral-200 underline self-start transition-colors"
                        >
                            {sendingReset ? 'Envoi en cours…' : 'Envoyer un lien de réinitialisation par courriel'}
                        </button>
                    </div>

                    {needsCurrentPassword && (
                        <Input
                            label="Mot de passe actuel *"
                            type="password"
                            value={formData.currentPassword}
                            onChange={(value) => handleInputChange('currentPassword', value)}
                            placeholder="Votre mot de passe"
                            error={errors.currentPassword}
                            description={emailChanged && formData.newPassword ? 'Requis pour confirmer le changement de courriel et de mot de passe' : emailChanged ? 'Requis pour confirmer le changement de courriel' : 'Requis pour confirmer le changement de mot de passe'}
                        />
                    )}
                </div>
            )}
        </Modal>
    );
};

export default UserEditModal;
