import { useEffect, useState } from 'react';
import { useConnection } from '../../../context/ConnectionContext';

const ACTIVE_ICON = 'assets/circle_active.svg';
const INACTIVE_ICON = 'assets/circle_inactive.svg';

function normalizeCode(raw) {
  return raw.toUpperCase().replace(/[^A-Z0-9]/g, '').slice(0, 6);
}

function ProjectCard({ project, users, invitesDisabled, isOwner, api, onChange, onDeleted }) {
  const [menuOpen, setMenuOpen] = useState(false);
  const [permDraft, setPermDraft] = useState(project.permanent?.code ?? '');
  const [error, setError] = useState(null);
  // Two-step delete: 0 = idle, 1 = irreversible-warning, 2 = type-name-to-confirm.
  const [deleteStep, setDeleteStep] = useState(0);
  const [deleteName, setDeleteName] = useState('');
  const [deleting, setDeleting] = useState(false);

  useEffect(() => {
    setPermDraft(project.permanent?.code ?? '');
  }, [project.permanent?.code]);

  const memberSet = new Set(project.members.map((m) => m.toLowerCase()));

  const toggleMember = async (username, member) => {
    const result = await api.setProjectMember(project.id, username, member);
    if (result.ok) onChange(result.project);
    else setError(result.error ?? 'Could not update members.');
  };

  const savePermanent = async (code, active) => {
    setError(null);
    const result = await api.setPermanentCode(project.id, code, active);
    if (result.ok) onChange(result.project);
    else setError(result.error ?? 'Invalid invite code.');
  };

  const regenerate = async () => {
    const result = await api.regenerateTemporaryCode(project.id);
    if (result.ok) onChange({ ...project, temporary: { code: result.code } });
    else setError(result.error ?? 'Could not regenerate code.');
  };

  const permActive = Boolean(project.permanent?.active);

  const cancelDelete = () => {
    setDeleteStep(0);
    setDeleteName('');
  };

  const confirmDelete = async () => {
    if (deleteName !== project.name) return;
    setDeleting(true);
    setError(null);
    const result = await api.deleteProject(project.id);
    setDeleting(false);
    if (result.ok) {
      onDeleted(project.id);
    } else {
      setError(result.error ?? 'Could not delete project.');
      cancelDelete();
    }
  };

  return (
    <li className="project-mgmt-card">
      <div className="project-mgmt-header">
        <span className="project-mgmt-name">{project.name}</span>
        <div className="project-mgmt-members">
          <button type="button" className="project-mgmt-members-btn" onClick={() => setMenuOpen((o) => !o)}>
            {project.members.length} member{project.members.length === 1 ? '' : 's'} ▾
          </button>
          {menuOpen && (
            <div className="project-mgmt-checklist">
              {users.map((user) => (
                <label key={user.username} className="project-mgmt-check">
                  <input
                    type="checkbox"
                    checked={memberSet.has(user.username.toLowerCase())}
                    onChange={(e) => toggleMember(user.username, e.target.checked)}
                  />
                  {user.displayName}
                </label>
              ))}
            </div>
          )}
        </div>
      </div>

      <div className="project-mgmt-code-row">
        <span className="project-mgmt-code-label">Permanent</span>
        {invitesDisabled ? (
          <span className="project-mgmt-na">N/A</span>
        ) : (
          <>
            <input
              type="text"
              className={`project-mgmt-code-input${permActive ? '' : ' project-mgmt-code-input--muted'}`}
              value={permDraft}
              maxLength={6}
              onChange={(e) => setPermDraft(normalizeCode(e.target.value))}
              onBlur={() => permDraft !== project.permanent?.code && savePermanent(permDraft, permActive)}
            />
            <button
              type="button"
              className="project-mgmt-toggle"
              aria-label={permActive ? 'Disable permanent code' : 'Enable permanent code'}
              title={permActive ? 'Enabled' : 'Disabled'}
              onClick={() => savePermanent(permDraft || project.permanent?.code || '', !permActive)}
            >
              <img src={permActive ? ACTIVE_ICON : INACTIVE_ICON} alt="" />
            </button>
          </>
        )}
      </div>

      <div className="project-mgmt-code-row">
        <span className="project-mgmt-code-label">Temporary</span>
        {invitesDisabled ? (
          <span className="project-mgmt-na">N/A</span>
        ) : (
          <>
            <input type="text" className="project-mgmt-code-input" value={project.temporary?.code ?? ''} readOnly />
            <button type="button" className="project-mgmt-refresh" aria-label="Generate new temporary code" onClick={regenerate}>
              <img src="assets/refresh.svg" alt="" />
            </button>
          </>
        )}
      </div>
      {error && <div className="project-mgmt-error">{error}</div>}

      {isOwner && (
        <div className="project-mgmt-danger">
          {deleteStep === 0 && (
            <button
              type="button"
              className="project-mgmt-delete-btn"
              onClick={() => setDeleteStep(1)}
            >
              Delete project
            </button>
          )}
          {deleteStep === 1 && (
            <div className="project-mgmt-delete-confirm">
              <p className="project-mgmt-delete-warning">
                This irreversibly deletes <strong>{project.name}</strong> and all of its
                data — revisions, files, locks, and invite codes. This cannot be undone.
              </p>
              <div className="project-mgmt-delete-actions">
                <button type="button" className="project-mgmt-delete-cancel" onClick={cancelDelete}>
                  Cancel
                </button>
                <button type="button" className="project-mgmt-delete-btn" onClick={() => setDeleteStep(2)}>
                  Continue
                </button>
              </div>
            </div>
          )}
          {deleteStep === 2 && (
            <div className="project-mgmt-delete-confirm">
              <p className="project-mgmt-delete-warning">
                Type the project name <strong>{project.name}</strong> to confirm deletion.
              </p>
              <input
                type="text"
                className="project-mgmt-delete-input"
                placeholder={project.name}
                value={deleteName}
                onChange={(e) => setDeleteName(e.target.value)}
                autoFocus
              />
              <div className="project-mgmt-delete-actions">
                <button type="button" className="project-mgmt-delete-cancel" onClick={cancelDelete}>
                  Cancel
                </button>
                <button
                  type="button"
                  className="project-mgmt-delete-btn"
                  disabled={deleteName !== project.name || deleting}
                  onClick={confirmDelete}
                >
                  {deleting ? 'Deleting…' : 'Delete'}
                </button>
              </div>
            </div>
          )}
        </div>
      )}
    </li>
  );
}

export function ProjectManagement() {
  const { api, account } = useConnection();
  const isOwner = account?.role === 'owner';
  const [projects, setProjects] = useState([]);
  const [users, setUsers] = useState([]);
  const [invitesDisabled, setInvitesDisabled] = useState(false);
  const [error, setError] = useState(null);
  const [newName, setNewName] = useState('');

  const load = async () => {
    const result = await api.getAdminProjects();
    if (result.ok) {
      setProjects(result.projects);
      setUsers(result.users ?? []);
      setInvitesDisabled(Boolean(result.inviteCodesDisabled));
    } else {
      setError(result.error ?? 'Could not load projects.');
    }
  };

  useEffect(() => { load(); }, [api]);

  const replaceProject = (updated) =>
    setProjects((ps) => ps.map((p) => (p.id === updated.id ? { ...p, ...updated } : p)));

  const removeProject = (id) => setProjects((ps) => ps.filter((p) => p.id !== id));

  const create = async () => {
    const name = newName.trim();
    if (!name) return;
    const result = await api.createProject(name);
    if (result.ok) {
      setNewName('');
      setError(null);
      await load();
    } else {
      setError(result.error ?? 'Could not create project.');
    }
  };

  return (
    <div className="project-mgmt">
      <h2 className="project-mgmt-title">Projects</h2>
      <div className="project-mgmt-new">
        <input
          type="text"
          className="project-mgmt-new-input"
          placeholder="New project name"
          value={newName}
          onChange={(e) => setNewName(e.target.value)}
          onKeyDown={(e) => e.key === 'Enter' && create()}
        />
        <button type="button" className="project-mgmt-new-btn" onClick={create}>New Project</button>
      </div>
      {error && <div className="project-mgmt-error">{error}</div>}
      <ul className="project-mgmt-list">
        {projects.map((project) => (
          <ProjectCard
            key={project.id}
            project={project}
            users={users}
            invitesDisabled={invitesDisabled}
            isOwner={isOwner}
            api={api}
            onChange={replaceProject}
            onDeleted={removeProject}
          />
        ))}
      </ul>
    </div>
  );
}
