import React, { useMemo, useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { Button, Modal, Spinner } from "react-bootstrap";
import { AuthService, EmployeeService, EventsService } from "../../services";
import { EMPLOYEE_PERMISSION_GROUPS } from "../../shared";

const SYSTEM_ACCESS_PERMISSION = "System Access";

const EmployeeList = () => {
  const navigate = useNavigate();
  const currentSite = EventsService.site || 3;
  const [employees, setEmployees] = useState([]);
  const [keyword, setKeyword] = useState('');
  const [showInactive, setShowInactive] = useState(false);
  const [hrUsers, setHrUsers] = useState([]);
  const [isHrLoading, setIsHrLoading] = useState(false);
  const [isSavingHrPermission, setIsSavingHrPermission] = useState(false);
  const [hrKeyword, setHrKeyword] = useState('');
  const [hrPermissionMap, setHrPermissionMap] = useState({});
  const [editingHrUser, setEditingHrUser] = useState(undefined);
  const [showHrPermissionModal, setShowHrPermissionModal] = useState(false);
  const [selectedHrPermissions, setSelectedHrPermissions] = useState([SYSTEM_ACCESS_PERMISSION]);

  useEffect(() => {
    if (!AuthService.canViewEmployees()) {
      window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
      AuthService.logout();
      navigate(`/login`);
    }
    EmployeeService.getAllEmployees().then((data) =>
      setEmployees(data.data)
    );
    loadHrUsers();
    loadHrPermissionsBySite(currentSite);
  }, []);

  const loadHrUsers = () => {
    setIsHrLoading(true);
    EmployeeService.getExternalEmployeesList()
      .then((response) => {
        setHrUsers(Array.isArray(response?.data) ? response.data : []);
      })
      .catch((error) => {
        window.alert(error?.response?.data?.message || 'Failed to load HR users.');
      })
      .finally(() => {
        setIsHrLoading(false);
      });
  };

  const loadHrPermissionsBySite = (site) => {
    EmployeeService.getExternalUserPermissionsList(site)
      .then((response) => {
        const nextMap = {};
        (Array.isArray(response?.data) ? response.data : []).forEach((item) => {
          const key = item?.external_user_id;
          if (!key) return;
          nextMap[key] = Array.isArray(item?.permissions) ? item.permissions : [];
        });
        setHrPermissionMap(nextMap);
      })
      .catch(() => {
        setHrPermissionMap({});
      });
  };

  const redirectToAdmin = () => {
    navigate(`/admin/customer-report`)
  }

  const goToEdit = (id) => {
    navigate(`/employees/edit/${id}`)
  }


  const goToView = (id) => {
    navigate(`/employees/${id}`)
  }

  const goToCreate = () => {
    navigate(`/employees`)
  }

  const goToExternalImport = () => {
    navigate(`/employees/external-import`);
  }

  const filteredHrUsers = useMemo(() => {
    return (hrUsers || [])
      .filter((item) => Number(item?.site) === Number(currentSite))
      .filter((item) => {
        const configuredPermissions = hrPermissionMap?.[item?.employee_id] || [];
        return configuredPermissions.length > 0;
      })
      .filter((item) => {
        if (!hrKeyword) return true;
        const key = hrKeyword.toLowerCase();
        return (
          (item?.username || '').toLowerCase().includes(key) ||
          (item?.name || '').toLowerCase().includes(key) ||
          (item?.title || '').toLowerCase().includes(key)
        );
      });
  }, [hrUsers, hrKeyword, hrPermissionMap, currentSite]);

  const openHrPermissionModal = (hrUser) => {
    setEditingHrUser(hrUser);
    const existingPermissions = hrPermissionMap?.[hrUser?.employee_id] || [];
    setSelectedHrPermissions(Array.from(new Set([SYSTEM_ACCESS_PERMISSION, ...existingPermissions])));
    setShowHrPermissionModal(true);
  };

  const closeHrPermissionModal = () => {
    if (isSavingHrPermission) return;
    setShowHrPermissionModal(false);
    setEditingHrUser(undefined);
    setSelectedHrPermissions([SYSTEM_ACCESS_PERMISSION]);
  };

  const toggleHrPermission = (permissionKey) => {
    if (permissionKey === SYSTEM_ACCESS_PERMISSION) return;
    setSelectedHrPermissions((prev) => {
      if (prev.includes(permissionKey)) {
        return prev.filter((item) => item !== permissionKey);
      }
      return [...prev, permissionKey];
    });
  };

  const isHrPermissionGroupFullySelected = (permissionItems = []) => {
    return permissionItems.length > 0 && permissionItems.every((permissionKey) => selectedHrPermissions.includes(permissionKey));
  };

  const toggleHrPermissionGroup = (permissionItems = [], checked) => {
    if (!Array.isArray(permissionItems) || permissionItems.length === 0) return;
    setSelectedHrPermissions((prev) => {
      const nextSet = new Set(prev);
      permissionItems.forEach((permissionKey) => {
        if (permissionKey === SYSTEM_ACCESS_PERMISSION) {
          nextSet.add(SYSTEM_ACCESS_PERMISSION);
          return;
        }
        if (checked) {
          nextSet.add(permissionKey);
        } else {
          nextSet.delete(permissionKey);
        }
      });
      return Array.from(nextSet);
    });
  };

  const saveHrPermissions = () => {
    if (!editingHrUser?.employee_id) return;
    setIsSavingHrPermission(true);
    EmployeeService.saveExternalUserPermission({
      external_user_id: editingHrUser.employee_id,
      username: editingHrUser.username || '',
      name: editingHrUser.name || '',
      email: editingHrUser.email || '',
      allow_site: Number(currentSite),
      permissions: selectedHrPermissions
    })
      .then(() => {
        setHrPermissionMap((prev) => ({
          ...prev,
          [editingHrUser.employee_id]: Array.from(new Set([SYSTEM_ACCESS_PERMISSION, ...selectedHrPermissions]))
        }));
        closeHrPermissionModal();
      })
      .catch((error) => {
        window.alert(error?.response?.data?.message || 'Failed to save HR user permissions.');
      })
      .finally(() => {
        setIsSavingHrPermission(false);
      });
  };

  const revokeHrPermissions = (hrUser) => {
    if (!hrUser?.employee_id) return;
    if (!window.confirm(`Revoke all permissions for ${hrUser?.username || 'this HR user'} on Site ${currentSite}?`)) {
      return;
    }
    EmployeeService.revokeExternalUserPermission(hrUser.employee_id, Number(currentSite))
      .then(() => {
        setHrPermissionMap((prev) => {
          const next = { ...prev };
          delete next[hrUser.employee_id];
          return next;
        });
      })
      .catch((error) => {
        window.alert(error?.response?.data?.message || 'Failed to revoke HR user permissions.');
      });
  };

  
  return (
    <>
      <div className="list row mb-4">
        <div className="col-md-12 text-primary">
           <h5>
            All Employees
            {AuthService.canAddOrEditEmployees() && (
              <button className="btn btn-primary btn-sm ms-2" onClick={() => goToCreate()}>
                Add New Employee
              </button>
            )}
            {AuthService.canAddOrEditEmployees() && (
              <button className="btn btn-primary btn-sm ms-2" onClick={() => goToExternalImport()}>
                Add New Employee From HR System
              </button>
            )}
          </h5> 
        </div>
      </div>
      <div className="list row mb-4">
        <div className="col-md-12">
          <h6 className="text-primary">HR System Users</h6>
          <div className="mb-3 d-flex align-items-center" style={{ gap: '12px', flexWrap: 'wrap' }}>
            <label>
              Site: <strong className="ms-2">{currentSite}</strong>
            </label>
            <label>
              Filter:
              <input className="ms-2" type="text" value={hrKeyword} onChange={(e) => setHrKeyword(e.currentTarget.value)} />
            </label>
            <button className="btn btn-primary btn-sm" onClick={() => {loadHrUsers(); loadHrPermissionsBySite(currentSite);}} disabled={isHrLoading}>
              {isHrLoading ? 'Loading...' : 'Refresh HR Users'}
            </button>
          </div>
          <table className="personnel-info-table mb-5">
            <thead>
              <tr>
                <th>Username</th>
                <th>Name</th>
                <th>Title</th>
                <th>Site</th>
                <th>Configured Permissions</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {isHrLoading && (
                <tr>
                  <td colSpan={6}><Spinner size="sm" className="me-2" />Loading HR users...</td>
                </tr>
              )}
              {!isHrLoading && filteredHrUsers.map((hrUser) => {
                const configuredPermissions = hrPermissionMap?.[hrUser?.employee_id] || [];
                return (
                  <tr key={`${hrUser?.employee_id}-${hrUser?.site}`}>
                    <td>{hrUser?.username}</td>
                    <td>{hrUser?.name}</td>
                    <td>{hrUser?.title}</td>
                    <td>{hrUser?.site}</td>
                    <td>{configuredPermissions.length > 0 ? configuredPermissions.join(', ') : '-'}</td>
                    <td>
                      <button className="btn btn-primary btn-sm me-2" onClick={() => openHrPermissionModal(hrUser)}>Edit</button>
                      <button className="btn btn-danger btn-sm" onClick={() => revokeHrPermissions(hrUser)}>Revoke</button>
                    </td>
                  </tr>
                );
              })}
              {!isHrLoading && filteredHrUsers.length === 0 && (
                <tr>
                  <td colSpan={6} style={{ textAlign: 'center' }}>No HR users found for selected site.</td>
                </tr>
              )}
            </tbody>
          </table>

          <h6 className="text-primary">Internal Employees</h6>
          <div className="mb-4">Filter By Name: <input type="text" value={keyword} onChange={(e) => setKeyword(e.currentTarget.value)}/></div>
          <input className="mb-4 me-2" type="checkbox" value={showInactive} checked={showInactive === true} onChange={() => setShowInactive(!showInactive)} />
            Show Inactive Employees
          <table className="personnel-info-table"> 
            <thead>
              <tr>
                <th>Name</th>
                <th>Preferred Name</th>
                <th>Username</th>
                <th>Status</th>
                <th>Permissions</th>
                <th></th>
              </tr>
              
            </thead>
            <tbody>
              {
                employees && employees.filter(item => showInactive ? item : item.status === 'active').filter((item)=> item?.name.toLowerCase().includes(keyword.toLowerCase())).map(employee => <tr key={employee.id}>
                  <td>{employee?.name}</td>
                  <td>{employee?.name_cn}</td>
                  <td>{employee?.username}</td>
                  <td>{employee?.status}</td>
                  <td>{employee?.permissions?.join(', ') || '-'}</td>
                  <td>
                    {AuthService.canAddOrEditEmployees() && <button className="btn btn-primary btn-sm me-2" onClick={() => goToEdit(employee?.id)}>Edit</button> }
                    {AuthService.canViewEmployees() && <button className="btn btn-default btn-sm me-2" onClick={() => goToView(employee?.id)}>View</button>}
                  </td>
                </tr>)
              }
            </tbody>
          </table>
           
        </div>
      </div>
      <Modal show={showHrPermissionModal} onHide={closeHrPermissionModal} size="lg">
        <Modal.Header closeButton>
          <Modal.Title>Edit HR User Permissions - {editingHrUser?.username}</Modal.Title>
        </Modal.Header>
        <Modal.Body>
          <div className="mb-3">
            <strong>Allow Site:</strong> {currentSite}
          </div>
          {Object.entries(EMPLOYEE_PERMISSION_GROUPS).map(([groupName, permissionItems]) => (
            <div key={groupName} className="mb-3">
              <div className="d-flex align-items-center justify-content-between mb-1" style={{ gap: '16px' }}>
                <div className="text-primary">{groupName}</div>
                <label>
                  <input
                    type="checkbox"
                    className="me-2"
                    checked={isHrPermissionGroupFullySelected(permissionItems)}
                    onChange={(e) => toggleHrPermissionGroup(permissionItems, e.currentTarget.checked)}
                    disabled={groupName === 'System'}
                  />
                  Select All
                </label>
              </div>
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: '10px 18px' }}>
                {permissionItems.map((permissionKey) => (
                  <label key={permissionKey} style={{ minWidth: '280px' }}>
                    <input
                      type="checkbox"
                      className="me-2"
                      checked={selectedHrPermissions.includes(permissionKey)}
                      onChange={() => toggleHrPermission(permissionKey)}
                      disabled={permissionKey === SYSTEM_ACCESS_PERMISSION}
                    />
                    {permissionKey}{permissionKey === SYSTEM_ACCESS_PERMISSION ? ' (required)' : ''}
                  </label>
                ))}
              </div>
            </div>
          ))}
        </Modal.Body>
        <Modal.Footer>
          <Button variant="secondary" onClick={closeHrPermissionModal} disabled={isSavingHrPermission}>
            Cancel
          </Button>
          <Button variant="primary" onClick={saveHrPermissions} disabled={isSavingHrPermission}>
            {isSavingHrPermission ? <><Spinner size="sm" className="me-2" />Saving...</> : 'Done'}
          </Button>
        </Modal.Footer>
      </Modal>
    </>
  )
};

export default EmployeeList;