import React, { useEffect, useMemo, useState } from 'react';
import DataTable from '../components/DataTable';
import { rolesAPI, listPermissions } from '../services/api';
import { Plus, Trash2, Search, Pencil } from 'lucide-react';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { getErrorMessage, getSuccessMessage } from '../utils/errorHandler';

const Roles = () => {
  const [roles, setRoles] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');
  const [name, setName] = useState('');
  const [permissionsInput, setPermissionsInput] = useState('');
  const [nameFilter, setNameFilter] = useState('');
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [isEditModalOpen, setIsEditModalOpen] = useState(false);
  const [editingRole, setEditingRole] = useState(null);
  const [selectedPermissions, setSelectedPermissions] = useState([]);

  const [permissionOptions, setPermissionOptions] = useState([]);

  const fetchRoles = async (q = '') => {
    try {
      setLoading(true);
      const list = await rolesAPI.list(q);
      setRoles(list);
    } catch (e) {
      const errorMsg = getErrorMessage(e);
      setError(errorMsg);
      toast.error(errorMsg);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchRoles();
    (async () => {
      try {
        const perms = await listPermissions();
        setPermissionOptions(Array.isArray(perms) ? perms : []);
      } catch (_) {
        setPermissionOptions([]);
      }
    })();
  }, []);

  const onAddRole = async (e) => {
    e.preventDefault();
    if (!name.trim()) return;
    const perms = selectedPermissions.length > 0
      ? selectedPermissions
      : permissionsInput.split(',').map(p => p.trim()).filter(Boolean);
    try {
      await rolesAPI.create({ name: name.trim(), permissions: perms });
      setName('');
      setPermissionsInput('');
      setSelectedPermissions([]);
      await fetchRoles(nameFilter);
      setIsModalOpen(false);
      toast.success('Role created successfully');
    } catch (err) {
      const errorMsg = getErrorMessage(err);
      setError(errorMsg);
      toast.error(errorMsg);
    }
  };

  const onDelete = async (id) => {
    try {
      await rolesAPI.remove(id);
      await fetchRoles(nameFilter);
      toast.success('Role deleted successfully');
    } catch (err) {
      toast.error(getErrorMessage(err));
    }
  };

  const openEdit = (role) => {
    setEditingRole(role);
    setName(role.name || '');
    setSelectedPermissions(Array.isArray(role.permissions) ? role.permissions : []);
    setPermissionsInput('');
    setIsEditModalOpen(true);
  };

  const onUpdateRole = async (e) => {
    e.preventDefault();
    if (!editingRole) return;
    const perms = selectedPermissions.length > 0
      ? selectedPermissions
      : permissionsInput.split(',').map(p => p.trim()).filter(Boolean);
    try {
      await rolesAPI.update(editingRole.id, { name: name.trim(), permissions: perms });
      await fetchRoles(nameFilter);
      setIsEditModalOpen(false);
      setEditingRole(null);
      setName('');
      setPermissionsInput('');
      setSelectedPermissions([]);
      toast.success('Role updated successfully');
    } catch (err) {
      const errorMsg = getErrorMessage(err);
      setError(errorMsg);
      toast.error(errorMsg);
    }
  };

  const columns = useMemo(() => [
    { key: 'name', header: 'Name' },
    { key: 'permissions', header: 'Permissions', render: (val) => Array.isArray(val) ? val.join(', ') : '' },
    { key: 'userType', header: 'User Type' },
    { key: 'actions', header: 'Actions', render: (_val, row) => (
      <div className="flex items-center gap-x-2 ">
        <button
          onClick={() => openEdit(row)}
          className="inline-flex items-center px-3 py-1 text-sm rounded-md bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-300 hover:opacity-90"
        >
          <Pencil className="h-4 w-4 mr-1" /> Edit
        </button>
        <button
          onClick={() => onDelete(row.id)}
          className="inline-flex items-center px-3 py-1 text-sm rounded-md bg-red-100 text-red-700 dark:bg-red-900 dark:text-red-300 hover:opacity-90"
        >
          <Trash2 className="h-4 w-4 mr-1" /> Delete
        </button>
      </div>
    ) },
  ], []);

  return (
    <div className="p-6">
      <ToastContainer position="top-right" autoClose={3000} />
      <div className="mb-6 flex items-start justify-between">
        <div>
          <h1 className="text-2xl font-bold text-gray-900 dark:text-white">Roles</h1>
          <p className="text-gray-600 dark:text-gray-400">Manage roles: add, filter by name, and delete</p>
        </div>
        <button
          onClick={() => setIsModalOpen(true)}
          className="btn-primary inline-flex items-center"
        >
          <Plus className="h-4 w-4 mr-2" /> Add Role
        </button>
      </div>

      {/* Add Role Modal */}
      {isModalOpen && (
        <>
          <div
            className="fixed inset-0 bg-black bg-opacity-50 z-40"
            onClick={() => setIsModalOpen(false)}
          />
          <div className="fixed inset-0 z-50 flex items-center justify-center p-4">
            <div className="w-full max-w-2xl card p-6 relative">
              <div className="mb-4">
                <h3 className="text-lg font-semibold text-gray-900 dark:text-white">Add Role</h3>
                <p className="text-sm text-gray-600 dark:text-gray-400">Create a new role with permissions</p>
              </div>
              <form className="space-y-4" onSubmit={onAddRole}>
                <div>
                  <label className="block text-sm mb-1 text-gray-700 dark:text-gray-300">Role Name</label>
                  <input
                    value={name}
                    onChange={(e) => setName(e.target.value)}
                    className="w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-primary-500"
                    placeholder="e.g., Admin"
                  />
                </div>
                <div>
                  <label className="block text-sm mb-2 text-gray-700 dark:text-gray-300">Permissions</label>
                  <div className="flex items-center gap-2 mb-2">
                    <button
                      type="button"
                      onClick={() => setSelectedPermissions(permissionOptions.map(p => typeof p === 'string' ? p : p?.name).filter(Boolean))}
                      className="text-xs border px-2 py-1 rounded bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-200 hover:bg-primary-50 dark:hover:bg-gray-600 transition"
                    >
                      Select All
                    </button>
                    <button
                      type="button"
                      onClick={() => setSelectedPermissions([])}
                      className="text-xs border px-2 py-1 rounded bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-200 hover:bg-red-50 dark:hover:bg-gray-600 transition"
                    >
                      Clear
                    </button>
                  </div>
                  <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-3 max-h-48 overflow-y-auto border rounded-lg p-3 bg-gray-50 dark:bg-gray-800">
                    {permissionOptions.map((perm) => {
                      const permName = typeof perm === 'string' ? perm : perm?.name;
                      const permDesc = typeof perm === 'object' ? perm?.description : undefined;
                      const checked = selectedPermissions.includes(permName);
                      return (
                        <label key={permName}
                          className="flex items-start gap-x-2 cursor-pointer border border-gray-200 dark:border-gray-700 rounded-md bg-white dark:bg-gray-900 px-2 py-2 shadow-sm hover:border-primary-400 dark:hover:border-primary-600 relative transition"
                        >
                          <input
                            type="checkbox"
                            className="mt-1 h-4 w-4 text-primary-600 border-gray-300 rounded"
                            checked={checked}
                            onChange={(e) => {
                              if (e.target.checked) {
                                setSelectedPermissions((prev) => [...prev, permName]);
                              } else {
                                setSelectedPermissions((prev) => prev.filter(p => p !== permName));
                              }
                            }}
                          />
                          <span className="text-sm text-gray-700 dark:text-gray-200 flex flex-col">
                            <span
                              title={permDesc || ''}
                              className={permDesc ? 'underline decoration-dotted decoration-gray-400 cursor-help' : ''}
                            >
                            {permName}
                            </span>
                            {permDesc && (
                              <span className="text-xs text-gray-400 dark:text-gray-400 mt-1 ">{permDesc}</span>
                            )}
                          </span>
                        </label>
                      );
                    })}
                  </div>
                  <div className="mt-4 p-3 rounded bg-gray-100 dark:bg-gray-700 border border-gray-200 dark:border-gray-600">
                    <label className="block text-xs mb-1 text-gray-500 dark:text-gray-400">Custom permissions (comma separated)</label>
                    <input
                      value={permissionsInput}
                      onChange={(e) => setPermissionsInput(e.target.value)}
                      className="w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-primary-500"
                      placeholder="Administrator, RoleManagement"
                    />
                  </div>
                </div>
                <div className="flex items-center justify-end gap-x-2">
                  <button
                    type="button"
                    onClick={() => setIsModalOpen(false)}
                    className="inline-flex items-center px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-800"
                  >
                    Cancel
                  </button>
                  <button type="submit" className="btn-primary inline-flex items-center">
                    <Plus className="h-4 w-4 mr-2" /> Create Role
                  </button>
                </div>
              </form>
            </div>
          </div>
        </>
      )}

      {/* Edit Role Modal */}
      {isEditModalOpen && (
        <>
          <div
            className="fixed inset-0 bg-black bg-opacity-50 z-40"
            onClick={() => setIsEditModalOpen(false)}
          />
          <div className="fixed inset-0 z-50 flex items-center justify-center p-4">
            <div className="w-full max-w-2xl card p-6 relative">
              <div className="mb-4">
                <h3 className="text-lg font-semibold text-gray-900 dark:text-white">Edit Role</h3>
                <p className="text-sm text-gray-600 dark:text-gray-400">Update role name and permissions</p>
              </div>
              <form className="space-y-4" onSubmit={onUpdateRole}>
                <div>
                  <label className="block text-sm mb-1 text-gray-700 dark:text-gray-300">Role Name</label>
                  <input
                    value={name}
                    onChange={(e) => setName(e.target.value)}
                    className="w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-primary-500"
                    placeholder="e.g., Admin"
                  />
                </div>
                <div>
                  <label className="block text-sm mb-2 text-gray-700 dark:text-gray-300">Permissions</label>
                  <div className="flex items-center gap-2 mb-2">
                    <button
                      type="button"
                      onClick={() => setSelectedPermissions(permissionOptions.map(p => typeof p === 'string' ? p : p?.name).filter(Boolean))}
                      className="text-xs border px-2 py-1 rounded bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-200 hover:bg-primary-50 dark:hover:bg-gray-600 transition"
                    >
                      Select All
                    </button>
                    <button
                      type="button"
                      onClick={() => setSelectedPermissions([])}
                      className="text-xs border px-2 py-1 rounded bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-200 hover:bg-red-50 dark:hover:bg-gray-600 transition"
                    >
                      Clear
                    </button>
                  </div>
                  <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-3 max-h-48 overflow-y-auto border rounded-lg p-3 bg-gray-50 dark:bg-gray-800">
                    {permissionOptions.map((perm) => {
                      const permName = typeof perm === 'string' ? perm : perm?.name;
                      const permDesc = typeof perm === 'object' ? perm?.description : undefined;
                      const checked = selectedPermissions.includes(permName);
                      return (
                        <label key={permName}
                          className="flex items-start gap-x-2 cursor-pointer border border-gray-200 dark:border-gray-700 rounded-md bg-white dark:bg-gray-900 px-2 py-2 shadow-sm hover:border-primary-400 dark:hover:border-primary-600 relative transition"
                        >
                          <input
                            type="checkbox"
                            className="mt-1 h-4 w-4 text-primary-600 border-gray-300 rounded"
                            checked={checked}
                            onChange={(e) => {
                              if (e.target.checked) {
                                setSelectedPermissions((prev) => [...prev, permName]);
                              } else {
                                setSelectedPermissions((prev) => prev.filter(p => p !== permName));
                              }
                            }}
                          />
                          <span className="text-sm text-gray-700 dark:text-gray-200 flex flex-col">
                            <span
                              title={permDesc || ''}
                              className={permDesc ? 'underline decoration-dotted decoration-gray-400 cursor-help' : ''}
                            >
                            {permName}
                            </span>
                            {permDesc && (
                              <span className="text-xs text-gray-400 dark:text-gray-400 mt-1 ">{permDesc}</span>
                            )}
                          </span>
                        </label>
                      );
                    })}
                  </div>
                  <div className="mt-4 p-3 rounded bg-gray-100 dark:bg-gray-700 border border-gray-200 dark:border-gray-600">
                    <label className="block text-xs mb-1 text-gray-500 dark:text-gray-400">Custom permissions (comma separated)</label>
                    <input
                      value={permissionsInput}
                      onChange={(e) => setPermissionsInput(e.target.value)}
                      className="w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-primary-500"
                      placeholder="Administrator, RoleManagement"
                    />
                  </div>
                </div>
                <div className="flex items-center justify-end gap-x-2">
                  <button
                    type="button"
                    onClick={() => setIsEditModalOpen(false)}
                    className="inline-flex items-center px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-800"
                  >
                    Cancel
                  </button>
                  <button type="submit" className="btn-primary inline-flex items-center">
                    <Pencil className="h-4 w-4 mr-2" /> Update Role
                  </button>
                </div>
              </form>
            </div>
          </div>
        </>
      )}

      {/* Filter by name */}
      <div className="card p-4 mb-4">
        <div className="relative max-w-md">
          <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-gray-400" />
          <input
            value={nameFilter}
            onChange={async (e) => {
              const v = e.target.value;
              setNameFilter(v);
              await fetchRoles(v);
            }}
            placeholder="Filter by role name"
            className="w-full pl-10 pr-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100"
          />
        </div>
      </div>

      <DataTable
        data={roles}
        columns={columns}
        loading={loading}
        searchable={false}
        className=""
      />

      {error && (
        <div className="mt-4 text-sm text-red-600 dark:text-red-400">{error}</div>
      )}
    </div>
  );
};

export default Roles;


