import React, { useEffect, useMemo, useRef, useState } from 'react';
import { FiPlus, FiTrash2, FiEdit2, FiUser, FiShield, FiArrowLeft } from 'react-icons/fi';
import Modal from './Modal';
import LoadingOverlay from './LoadingOverlay';
import ConfirmDialog from './ConfirmDialog';
import { adminsAPI, domainsAPI } from '../services/api';

/**
 * Two-pane modal:
 *   - 'list'   shows all admins
 *   - 'form'   shows create/edit form
 *
 * editTarget is null for "create new" or an existing admin for "edit".
 */
const AdminUsersModal = ({ open, currentUser, onClose, onToast }) => {
  const [view, setView] = useState('list');
  const [admins, setAdmins] = useState([]);
  const [domains, setDomains] = useState([]);
  const [loading, setLoading] = useState(false);
  const [editTarget, setEditTarget] = useState(null);
  const [deleteTarget, setDeleteTarget] = useState(null);

  const reload = async () => {
    setLoading(true);
    try {
      const [a, d] = await Promise.all([
        adminsAPI.list(),
        domainsAPI.list(false),
      ]);
      setAdmins(a);
      setDomains(d);
    } catch (err) {
      onToast?.(`Failed to load admins: ${err.message}`, 'error');
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    if (open) {
      setView('list');
      setEditTarget(null);
      reload();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open]);

  const handleDelete = async () => {
    if (!deleteTarget) return;
    try {
      await adminsAPI.remove(deleteTarget);
      onToast?.(`Deleted ${deleteTarget}`, 'success');
      setDeleteTarget(null);
      await reload();
    } catch (err) {
      onToast?.(`Delete failed: ${err.message}`, 'error');
    }
  };

  return (
    <Modal
      open={open}
      onClose={onClose}
      title={view === 'list' ? 'Manage admins' : (editTarget ? 'Edit admin' : 'New admin')}
      subtitle={view === 'list' ? 'Super admins and per-domain admins' : null}
      size="lg"
    >
      <div className="relative min-h-[300px]">
        {loading && <LoadingOverlay message="Loading..." />}

        {view === 'list' && !loading && (
          <AdminList
            admins={admins}
            currentUserEmail={currentUser?.email}
            onCreate={() => { setEditTarget(null); setView('form'); }}
            onEdit={(a) => { setEditTarget(a); setView('form'); }}
            onDelete={(email) => setDeleteTarget(email)}
          />
        )}

        {view === 'form' && !loading && (
          <AdminForm
            target={editTarget}
            domains={domains}
            currentUserEmail={currentUser?.email}
            onCancel={() => { setView('list'); setEditTarget(null); }}
            onSaved={async () => {
              await reload();
              setView('list');
              setEditTarget(null);
            }}
            onToast={onToast}
          />
        )}
      </div>

      <ConfirmDialog
        open={!!deleteTarget}
        title="Delete admin"
        message={deleteTarget ? `Permanently delete admin ${deleteTarget}?` : ''}
        confirmLabel="Delete"
        danger
        onConfirm={handleDelete}
        onClose={() => setDeleteTarget(null)}
      />
    </Modal>
  );
};

// ============================================================
// Sub: AdminList
// ============================================================
const AdminList = ({ admins, currentUserEmail, onCreate, onEdit, onDelete }) => {
  return (
    <div className="space-y-4">
      <div className="flex justify-end">
        <button onClick={onCreate} className="btn-primary">
          <FiPlus className="w-4 h-4 mr-2" />
          New admin
        </button>
      </div>

      {admins.length === 0 ? (
        <p className="text-sm text-gray-500 text-center py-8">No admins yet.</p>
      ) : (
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs uppercase tracking-wide text-gray-500 border-b border-gray-200">
                <th className="py-2 pr-4 font-semibold">Email</th>
                <th className="py-2 pr-4 font-semibold">Role</th>
                <th className="py-2 pr-4 font-semibold">Domains</th>
                <th className="py-2 pr-4 font-semibold">Status</th>
                <th className="py-2 pr-2 font-semibold">Actions</th>
              </tr>
            </thead>
            <tbody className="divide-y divide-gray-100">
              {admins.map((a) => {
                const isMe = a.email === currentUserEmail;
                return (
                  <tr key={a.email} className="align-top hover:bg-gray-50">
                    <td className="py-3 pr-4">
                      <div className="flex items-center gap-2">
                        {a.role === 'super_admin'
                          ? <FiShield className="w-4 h-4 text-primary-600" />
                          : <FiUser className="w-4 h-4 text-gray-400" />}
                        <span className="font-semibold text-gray-900">{a.email}</span>
                        {isMe && <span className="pill">you</span>}
                      </div>
                    </td>
                    <td className="py-3 pr-4">
                      {a.role === 'super_admin'
                        ? <span className="pill-success">super_admin</span>
                        : <span className="pill">domain_admin</span>}
                    </td>
                    <td className="py-3 pr-4">
                      {a.role === 'super_admin' ? (
                        <span className="text-xs text-gray-400 italic">all domains</span>
                      ) : (
                        <div className="flex flex-wrap gap-1">
                          {(a.allowed_domains || []).map((d) => (
                            <span key={d} className="pill">{d}</span>
                          ))}
                        </div>
                      )}
                    </td>
                    <td className="py-3 pr-4">
                      <span className={a.active ? 'pill-success' : 'pill-warn'}>
                        {a.active ? 'active' : 'disabled'}
                      </span>
                    </td>
                    <td className="py-3 pr-2">
                      <div className="flex flex-row flex-nowrap items-center gap-2">
                        <button
                          onClick={() => onEdit(a)}
                          className="btn-secondary"
                          title="Edit"
                        >
                          <FiEdit2 className="w-3.5 h-3.5 mr-1.5" />
                          Edit
                        </button>
                        <button
                          onClick={() => onDelete(a.email)}
                          className="btn-danger"
                          disabled={isMe}
                          title={isMe ? "You can't delete yourself" : 'Delete'}
                        >
                          <FiTrash2 className="w-3.5 h-3.5 mr-1.5" />
                          Delete
                        </button>
                      </div>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
};

// ============================================================
// Sub: AdminForm
// ============================================================
const AdminForm = ({ target, domains, currentUserEmail, onCancel, onSaved, onToast }) => {
  const isEdit = !!target;
  const isSelf = isEdit && target.email === currentUserEmail;

  const [email, setEmail] = useState(target?.email || '');
  const [password, setPassword] = useState('');
  const [confirmPw, setConfirmPw] = useState('');
  const [role, setRole] = useState(target?.role || 'domain_admin');
  const [allowedDomains, setAllowedDomains] = useState(
    new Set((target?.allowed_domains || []).map((d) => d.toLowerCase()))
  );
  const [active, setActive] = useState(target?.active ?? true);
  const [error, setError] = useState('');
  const [busy, setBusy] = useState(false);

  // Tracks whether the user has manually typed in the email field.
  // Once they have, we stop auto-filling to avoid clobbering their input.
  const [emailTouched, setEmailTouched] = useState(isEdit);
  const emailRef = useRef(null);

  const sortedDomainNames = useMemo(
    () => [...domains].map((d) => d.domain).sort(),
    [domains]
  );

  // Auto-fill email with "@<domain>" when creating a NEW domain_admin
  // and exactly one domain is selected, as long as the user hasn't
  // manually edited the email field yet.
  useEffect(() => {
    if (isEdit) return;
    if (role !== 'domain_admin') return;
    if (emailTouched) return;
    if (allowedDomains.size === 1) {
      const [onlyDomain] = [...allowedDomains];
      setEmail(`@${onlyDomain}`);
      // Place caret before the @ so the user can type the local part directly.
      requestAnimationFrame(() => {
        const el = emailRef.current;
        if (el && document.activeElement === el) {
          try { el.setSelectionRange(0, 0); } catch { /* ignore */ }
        }
      });
    } else if (allowedDomains.size === 0) {
      setEmail('');
    }
  }, [allowedDomains, role, isEdit, emailTouched]);

  // When the user focuses the email field for the first time after
  // an auto-fill, place the caret at position 0 so they can just type.
  const handleEmailFocus = () => {
    const el = emailRef.current;
    if (el && !emailTouched && email.startsWith('@')) {
      try { el.setSelectionRange(0, 0); } catch { /* ignore */ }
    }
  };

  const toggleDomain = (d) => {
    const next = new Set(allowedDomains);
    if (next.has(d)) next.delete(d); else next.add(d);
    setAllowedDomains(next);
  };

  const passwordOk = !password || (password.length >= 8 && password === confirmPw);
  const passwordMismatch = password.length > 0 && confirmPw.length > 0 && password !== confirmPw;
  const passwordTooShort = password.length > 0 && password.length < 8;

  // For new admins password is required.
  const passwordRequired = !isEdit;
  const passwordProvided = password.length > 0;

  const submit = async () => {
    setError('');

    if (!email.trim() || !email.includes('@')) {
      setError('Please enter a valid email.'); return;
    }
    if (passwordRequired && !passwordProvided) {
      setError('Password is required for new admins.'); return;
    }
    if (passwordProvided && !passwordOk) {
      if (passwordTooShort) setError('Password must have at least 8 characters.');
      else if (passwordMismatch) setError('Passwords do not match.');
      return;
    }
    if (role === 'domain_admin' && allowedDomains.size === 0) {
      setError('A domain admin needs at least one allowed domain.'); return;
    }

    setBusy(true);
    try {
      const allowedList = role === 'super_admin' ? [] : [...allowedDomains];

      if (isEdit) {
        const payload = { role, allowed_domains: allowedList, active };
        if (passwordProvided) payload.password = password;
        // Don't send forbidden fields when editing self.
        if (isSelf) {
          delete payload.role;
          delete payload.active;
        }
        await adminsAPI.update(target.email, payload);
        onToast?.(`Updated ${target.email}`, 'success');
      } else {
        await adminsAPI.create({
          email: email.trim().toLowerCase(),
          password,
          role,
          allowed_domains: allowedList,
        });
        onToast?.(`Created ${email.trim().toLowerCase()}`, 'success');
      }
      onSaved();
    } catch (err) {
      setError(err.message);
    } finally {
      setBusy(false);
    }
  };

  return (
    <div className="space-y-5">
      <button onClick={onCancel} className="btn-ghost -ml-2">
        <FiArrowLeft className="w-4 h-4 mr-1.5" />
        Back to list
      </button>

      <div>
        <label className="block text-sm font-semibold text-gray-700 mb-2">Email</label>
        <input
          ref={emailRef}
          type="email"
          value={email}
          onChange={(e) => { setEmail(e.target.value); setEmailTouched(true); }}
          onFocus={handleEmailFocus}
          className="input-field"
          disabled={isEdit}
          placeholder="admin@example.com"
        />
        {isEdit && (
          <p className="mt-1 text-xs text-gray-500">Email cannot be changed after creation.</p>
        )}
      </div>

      <div>
        <label className="block text-sm font-semibold text-gray-700 mb-2">
          {isEdit ? 'Set new password (leave empty to keep current)' : 'Password'}
        </label>
        <div className="grid grid-cols-2 gap-2">
          <input
            type="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            className={`input-field ${passwordTooShort ? 'border-red-500' : ''}`}
            placeholder="At least 8 characters"
          />
          <input
            type="password"
            value={confirmPw}
            onChange={(e) => setConfirmPw(e.target.value)}
            className={`input-field ${passwordMismatch ? 'border-red-500' : ''}`}
            placeholder="Confirm"
          />
        </div>
        {passwordTooShort && <p className="mt-1 text-xs text-red-600">Minimum 8 characters.</p>}
        {!passwordTooShort && passwordMismatch && (
          <p className="mt-1 text-xs text-red-600">Passwords do not match.</p>
        )}
      </div>

      <div>
        <label className="block text-sm font-semibold text-gray-700 mb-2">Role</label>
        <div className="flex gap-2">
          <button
            type="button"
            onClick={() => setRole('domain_admin')}
            disabled={isSelf}
            className={`flex-1 px-4 py-2 rounded-lg border-2 transition-all ${
              role === 'domain_admin'
                ? 'border-primary-600 bg-primary-50 text-primary-700 font-semibold'
                : 'border-gray-300 bg-white text-gray-700 hover:border-gray-400'
            } disabled:opacity-50 disabled:cursor-not-allowed`}
          >
            <FiUser className="inline w-4 h-4 mr-2" />
            Domain admin
          </button>
          <button
            type="button"
            onClick={() => setRole('super_admin')}
            disabled={isSelf}
            className={`flex-1 px-4 py-2 rounded-lg border-2 transition-all ${
              role === 'super_admin'
                ? 'border-primary-600 bg-primary-50 text-primary-700 font-semibold'
                : 'border-gray-300 bg-white text-gray-700 hover:border-gray-400'
            } disabled:opacity-50 disabled:cursor-not-allowed`}
          >
            <FiShield className="inline w-4 h-4 mr-2" />
            Super admin
          </button>
        </div>
        {isSelf && (
          <p className="mt-1 text-xs text-gray-500">You can't change your own role.</p>
        )}
      </div>

      {role === 'domain_admin' && (
        <div>
          <label className="block text-sm font-semibold text-gray-700 mb-2">
            Allowed domains ({allowedDomains.size}/{sortedDomainNames.length})
          </label>
          {sortedDomainNames.length === 0 ? (
            <p className="text-sm text-gray-500 italic">No domains in the system yet.</p>
          ) : (
            <div className="border border-gray-200 rounded-lg max-h-48 overflow-y-auto custom-scrollbar p-2 grid grid-cols-2 gap-1">
              {sortedDomainNames.map((d) => (
                <label
                  key={d}
                  className="flex items-center gap-2 p-2 rounded hover:bg-gray-50 cursor-pointer"
                >
                  <input
                    type="checkbox"
                    checked={allowedDomains.has(d)}
                    onChange={() => toggleDomain(d)}
                    className="w-4 h-4 text-primary-600 rounded border-gray-300 focus:ring-primary-500"
                  />
                  <span className="text-sm text-gray-800">{d}</span>
                </label>
              ))}
            </div>
          )}
          {!isEdit && allowedDomains.size === 1 && !emailTouched && (
            <p className="mt-2 text-xs text-gray-500">
              Email pre-filled with the selected domain. You can still edit it.
            </p>
          )}
        </div>
      )}

      {isEdit && !isSelf && (
        <div className="flex items-center justify-between p-4 bg-gray-50 rounded-lg border border-gray-200">
          <div>
            <h3 className="font-semibold text-gray-900 text-sm">Account active</h3>
            <p className="text-xs text-gray-600">
              Disabled accounts cannot log in.
            </p>
          </div>
          <button
            type="button"
            onClick={() => setActive(!active)}
            className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
              active ? 'bg-primary-600' : 'bg-gray-300'
            }`}
          >
            <span
              className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
                active ? 'translate-x-6' : 'translate-x-1'
              }`}
            />
          </button>
        </div>
      )}

      {error && <p className="text-sm text-red-600">{error}</p>}

      <div className="flex justify-end gap-2 pt-4 border-t border-gray-200">
        <button onClick={onCancel} className="btn-secondary px-4 py-2" disabled={busy}>
          Cancel
        </button>
        <button onClick={submit} className="btn-primary" disabled={busy}>
          {busy ? 'Saving...' : (isEdit ? 'Save changes' : 'Create admin')}
        </button>
      </div>
    </div>
  );
};

export default AdminUsersModal;