import React, { useCallback, useEffect, useState } from 'react';
import { usePage } from '@inertiajs/react';
import axios from 'axios';
import toast from 'react-hot-toast';

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

interface User {
    id: number;
    name: string;
    email: string;
    roles: Role[];
}

interface PaginatedUsers {
    data: User[];
    current_page: number;
    last_page: number;
    per_page: number;
    total: number;
}

export default function UserManagement() {
    const { auth } = usePage<{ auth: { user: { api_token: string } } }>().props;
    const token = auth?.user?.api_token;
    const authHeaders = { headers: { Authorization: `Bearer ${token}` } };

    // ── Data ───────────────────────────────────────────────────────────
    const [users, setUsers] = useState<User[]>([]);
    const [pagination, setPagination] = useState({ current_page: 1, last_page: 1, total: 0 });
    const [allRoles, setAllRoles] = useState<Role[]>([]);
    const [loading, setLoading] = useState(false);
    const [search, setSearch] = useState('');
    const [page, setPage] = useState(1);

    // ── Modal ──────────────────────────────────────────────────────────
    const [editingUser, setEditingUser] = useState<User | null>(null);
    const [formName, setFormName] = useState('');
    const [formEmail, setFormEmail] = useState('');
    const [formRoles, setFormRoles] = useState<number[]>([]);
    const [saving, setSaving] = useState(false);
    const [modalOpen, setModalOpen] = useState(false);

    // ── Fetch ──────────────────────────────────────────────────────────
    const fetchRoles = useCallback(async () => {
        try {
            const { data } = await axios.get('/api/roles', authHeaders);
            setAllRoles(data.result ?? []);
        } catch {
            toast.error('Failed to load roles');
        }
    }, []);

    const fetchUsers = useCallback(async (currentPage: number, searchTerm: string) => {
        setLoading(true);
        try {
            const params = new URLSearchParams({ page: String(currentPage) });
            if (searchTerm.trim()) params.append('search', searchTerm.trim());
            const { data } = await axios.get(`/api/users?${params.toString()}`, authHeaders);
            const payload: PaginatedUsers = data.result;
            setUsers(payload.data ?? []);
            setPagination({
                current_page: payload.current_page,
                last_page: payload.last_page,
                total: payload.total,
            });
        } catch {
            toast.error('Failed to load users');
        } finally {
            setLoading(false);
        }
    }, []);

    useEffect(() => { fetchRoles(); }, [fetchRoles]);

    useEffect(() => {
        const timer = setTimeout(() => {
            setPage(1);
            fetchUsers(1, search);
        }, 350);
        return () => clearTimeout(timer);
    }, [search]);

    useEffect(() => { fetchUsers(page, search); }, [page]);

    // ── Modal helpers ──────────────────────────────────────────────────
    const openCreateModal = () => {
        setEditingUser(null);
        setFormName('');
        setFormEmail('');
        setFormRoles([]);
        setModalOpen(true);
    };

    const openEditModal = (user: User) => {
        setEditingUser(user);
        setFormName(user.name);
        setFormEmail(user.email);
        setFormRoles(user.roles.map(r => r.id));
        setModalOpen(true);
    };

    const closeModal = () => setModalOpen(false);

    const toggleRole = (id: number) =>
        setFormRoles(prev => prev.includes(id) ? prev.filter(r => r !== id) : [...prev, id]);

    // ── CRUD ───────────────────────────────────────────────────────────
    const saveUser = async () => {
        if (!formName.trim()) { toast.error('Name is required'); return; }
        if (!formEmail.trim()) { toast.error('Email is required'); return; }
        if (formRoles.length === 0) { toast.error('Assign at least one role'); return; }

        setSaving(true);
        try {
            const payload = { name: formName.trim(), email: formEmail.trim(), roles: formRoles };

            if (editingUser) {
                const { data } = await axios.put(`/api/users/${editingUser.id}`, payload, authHeaders);
                const updated: User = data.result;
                setUsers(prev => prev.map(u => (u.id === editingUser.id ? updated : u)));
                toast.success('User updated successfully');
            } else {
                await axios.post('/api/users', payload, authHeaders);
                toast.success('User created — a temporary password has been generated');
                await fetchUsers(page, search);
            }
            closeModal();
        } catch (e: any) {
            const msg = e.response?.data?.errors
                ? Object.values<string[]>(e.response.data.errors).flat().join(' ')
                : e.response?.data?.message ?? 'Failed to save user';
            toast.error(msg);
        } finally {
            setSaving(false);
        }
    };

    const deleteUser = async (user: User) => {
        if (!confirm(`Delete user "${user.name}"? This cannot be undone.`)) return;
        try {
            await axios.delete(`/api/users/${user.id}`, authHeaders);
            setUsers(prev => prev.filter(u => u.id !== user.id));
            setPagination(p => ({ ...p, total: p.total - 1 }));
            toast.success('User deleted');
        } catch {
            toast.error('Failed to delete user');
        }
    };

    // ── UI helpers ─────────────────────────────────────────────────────
    const initials = (name: string) =>
        name.split(' ').slice(0, 2).map(p => p[0]?.toUpperCase() ?? '').join('');

    const avatarColor = (name: string) => {
        const colors = ['bg-indigo-500', 'bg-emerald-500', 'bg-rose-500', 'bg-amber-500', 'bg-sky-500', 'bg-violet-500'];
        let hash = 0;
        for (let i = 0; i < name.length; i++) hash = name.charCodeAt(i) + ((hash << 5) - hash);
        return colors[Math.abs(hash) % colors.length];
    };

    const pageButtons = Array.from({ length: pagination.last_page }, (_, i) => i + 1)
        .filter(p => Math.abs(p - page) <= 2 || p === 1 || p === pagination.last_page)
        .reduce<(number | 'ellipsis')[]>((acc, p, idx, arr) => {
            if (idx > 0 && p - (arr[idx - 1] as number) > 1) acc.push('ellipsis');
            acc.push(p);
            return acc;
        }, []);

    return (
        <div className="bg-white rounded-lg shadow">
            <div className="p-6">

                {/* Header */}
                <div className="flex flex-wrap justify-between items-center gap-3 mb-5">
                    {/* Search */}
                    <div className="mb-4">
                        <div className="relative max-w-sm">
                            <i className="ri ri-search-line absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 text-sm"></i>
                            <input
                                type="text"
                                value={search}
                                onChange={e => setSearch(e.target.value)}
                                placeholder="Search by name or email…"
                                className="w-full pl-9 pr-8 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
                            />
                            {search && (
                                <button
                                    type="button"
                                    onClick={() => setSearch('')}
                                    className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600"
                                >
                                    <i className="ri ri-close-line text-sm"></i>
                                </button>
                            )}
                        </div>
                    </div>
                    <div>
                        <button
                            type="button"
                            onClick={openCreateModal}
                            className="ti-btn ti-btn-primary py-2 px-3 whitespace-nowrap"
                        >
                            <i className="ri ri-user-add-line mr-2"></i> New User
                        </button>
                    </div>
                </div>



                {/* Table */}
                {loading ? (
                    <div className="flex justify-center items-center py-16">
                        <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-indigo-600"></div>
                    </div>
                ) : (
                    <>
                        <div className="border border-gray-200 rounded-lg overflow-hidden">
                            <table className="min-w-full divide-y divide-gray-200">
                                <thead className="bg-gray-50">
                                    <tr>
                                        <th className="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wide">User</th>
                                        <th className="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wide">Roles</th>
                                        <th className="px-4 py-3 text-right text-xs font-semibold text-gray-500 uppercase tracking-wide">Actions</th>
                                    </tr>
                                </thead>
                                <tbody className="divide-y divide-gray-100 bg-white">
                                    {users.length === 0 ? (
                                        <tr>
                                            <td colSpan={4} className="px-4 py-12 text-center text-sm text-gray-400">
                                                {search ? 'No users match your search.' : 'No users found. Create one to get started.'}
                                            </td>
                                        </tr>
                                    ) : users.map(user => (
                                        <tr key={user.id} className="hover:bg-gray-50 transition-colors">
                                            <td className="px-2 py-3 text-left">
                                                <div className="flex items-center gap-3">
                                                    <div className={`w-9 h-9 rounded-full flex items-center justify-center text-white text-sm font-semibold flex-shrink-0 ${avatarColor(user.name)}`}>
                                                        {initials(user.name)}
                                                    </div>
                                                    <div className="min-w-0">
                                                        <p className="text-sm font-medium text-gray-800 truncate">{user.name}</p>
                                                        <p className="text-xs text-gray-400 truncate">{user.email}</p>
                                                    </div>
                                                </div>
                                            </td>
                                            <td className="px-2 py-3 text-left">
                                                <div className="flex flex-wrap gap-1">
                                                    {user.roles.length > 0 ? user.roles.map(role => (
                                                        <span key={role.id} className="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-indigo-50 text-indigo-700">
                                                            {role.name}
                                                        </span>
                                                    )) : (
                                                        <span className="text-xs text-gray-400">No roles</span>
                                                    )}
                                                </div>
                                            </td>
                                            <td className="px-4 py-3 text-right">
                                                <div className="flex items-center justify-end gap-1">
                                                    <button
                                                        type="button"
                                                        onClick={() => openEditModal(user)}
                                                        className="p-1.5 text-indigo-400 hover:text-white hover:bg-indigo-500 rounded transition-colors"
                                                        title="Edit user"
                                                    >
                                                        <i className="ri ri-edit-line text-sm"></i>
                                                    </button>
                                                    <button
                                                        type="button"
                                                        onClick={() => deleteUser(user)}
                                                        className="p-1.5 text-red-400 hover:text-white hover:bg-red-500 rounded transition-colors"
                                                        title="Delete user"
                                                    >
                                                        <i className="ri ri-delete-bin-line text-sm"></i>
                                                    </button>
                                                </div>
                                            </td>
                                        </tr>
                                    ))}
                                </tbody>
                            </table>
                        </div>

                        {/* Pagination */}
                        {pagination.last_page > 1 && (
                            <div className="flex items-center justify-between mt-4">
                                <p className="text-xs text-gray-500">
                                    Page {pagination.current_page} of {pagination.last_page} &mdash; {pagination.total} user{pagination.total !== 1 ? 's' : ''}
                                </p>
                                <div className="flex gap-1 items-center">
                                    <button
                                        type="button"
                                        disabled={page <= 1}
                                        onClick={() => setPage(p => Math.max(1, p - 1))}
                                        className="px-3 py-1.5 text-xs border border-gray-300 rounded-lg hover:bg-gray-50 disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
                                    >
                                        <i className="ri ri-arrow-left-s-line"></i> Prev
                                    </button>
                                    {pageButtons.map((p, idx) =>
                                        p === 'ellipsis' ? (
                                            <span key={`e-${idx}`} className="px-2 text-xs text-gray-400">…</span>
                                        ) : (
                                            <button
                                                key={p}
                                                type="button"
                                                onClick={() => setPage(p as number)}
                                                className={`px-3 py-1.5 text-xs border rounded-lg transition-colors ${p === page ? 'bg-indigo-600 text-white border-indigo-600' : 'border-gray-300 hover:bg-gray-50'}`}
                                            >
                                                {p}
                                            </button>
                                        ),
                                    )}
                                    <button
                                        type="button"
                                        disabled={page >= pagination.last_page}
                                        onClick={() => setPage(p => Math.min(pagination.last_page, p + 1))}
                                        className="px-3 py-1.5 text-xs border border-gray-300 rounded-lg hover:bg-gray-50 disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
                                    >
                                        Next <i className="ri ri-arrow-right-s-line"></i>
                                    </button>
                                </div>
                            </div>
                        )}
                    </>
                )}
            </div>

            {/* Create / Edit Modal */}
            {modalOpen && (
                <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 backdrop-blur-sm p-4">
                    <div className="bg-white rounded-xl shadow-xl w-full max-w-md">
                        {/* Modal header */}
                        <div className="flex items-center justify-between px-5 py-4 border-b border-gray-200">
                            <h3 className="text-base font-semibold text-gray-800">
                                {editingUser ? `Edit: ${editingUser.name}` : 'Create New User'}
                            </h3>
                            <button
                                type="button"
                                onClick={closeModal}
                                className="p-1.5 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded transition-colors"
                            >
                                <i className="ri ri-close-line text-lg"></i>
                            </button>
                        </div>

                        {/* Modal body */}
                        <div className="px-5 py-5 space-y-4">
                            {/* Name */}
                            <div>
                                <label className="block text-sm font-medium text-gray-700 mb-1">
                                    Full Name <span className="text-red-500">*</span>
                                </label>
                                <input
                                    type="text"
                                    value={formName}
                                    onChange={e => setFormName(e.target.value)}
                                    placeholder="e.g. Jane Doe"
                                    className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
                                />
                            </div>

                            {/* Email */}
                            <div>
                                <label className="block text-sm font-medium text-gray-700 mb-1">
                                    Email Address <span className="text-red-500">*</span>
                                </label>
                                <input
                                    type="email"
                                    value={formEmail}
                                    onChange={e => setFormEmail(e.target.value)}
                                    placeholder="e.g. jane@example.com"
                                    className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
                                />
                                <p className="text-xs mt-1 text-gray-400">
                                    {editingUser
                                        ? 'Changing the email will trigger a new password to be generated.'
                                        : 'A temporary password will be auto-generated for the new user.'}
                                </p>
                            </div>

                            {/* Roles */}
                            <div>
                                <div className="flex justify-between items-center mb-2">
                                    <label className="block text-sm font-medium text-gray-700">
                                        Roles <span className="text-red-500">*</span>
                                    </label>
                                    <span className="text-xs text-gray-400">{formRoles.length} selected</span>
                                </div>
                                {allRoles.length === 0 ? (
                                    <p className="text-xs text-gray-400 italic">No roles available. Create roles first.</p>
                                ) : (
                                    <div className="border border-gray-200 rounded-lg divide-y divide-gray-100 max-h-48 overflow-y-auto">
                                        {allRoles.map(role => (
                                            <label
                                                key={role.id}
                                                className="flex items-center gap-3 px-3 py-2.5 cursor-pointer hover:bg-gray-50 transition-colors"
                                            >
                                                <input
                                                    type="checkbox"
                                                    checked={formRoles.includes(role.id)}
                                                    onChange={() => toggleRole(role.id)}
                                                    className="rounded text-indigo-600 cursor-pointer"
                                                />
                                                <span className="text-sm text-gray-700">{role.name}</span>
                                            </label>
                                        ))}
                                    </div>
                                )}
                            </div>
                        </div>

                        {/* Modal footer */}
                        <div className="flex items-center justify-end gap-2 px-5 py-4 border-t border-gray-200">
                            <button
                                type="button"
                                onClick={closeModal}
                                className="px-4 py-2 text-sm text-gray-600 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
                            >
                                Cancel
                            </button>
                            <button
                                type="button"
                                onClick={saveUser}
                                disabled={saving}
                                className="flex items-center gap-1.5 px-4 py-2 text-sm bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 disabled:opacity-60 transition-colors font-medium"
                            >
                                {saving ? (
                                    <>
                                        <span className="animate-spin h-3 w-3 border-2 border-white border-t-transparent rounded-full inline-block"></span>
                                        Saving…
                                    </>
                                ) : editingUser ? 'Save Changes' : 'Create User'}
                            </button>
                        </div>
                    </div>
                </div>
            )}
        </div>
    );
}

