import { useState, useEffect } from "react";
import { api } from "../api";
import type {
  GridMap,
  ListedMap,
  MapAccessRequest,
  MapPermission,
  MapRole,
  PublicAccess,
} from "../types";
import "./EditMapModal.css";

interface Props {
  map: GridMap | ListedMap;
  onClose: () => void;
  onUpdated: (updated: GridMap) => void;
}

export default function EditMapModal({ map, onClose, onUpdated }: Props) {
  const [name, setName] = useState(map.name);
  const [publicAccess, setPublicAccess] = useState<PublicAccess>(
    map.public_access,
  );
  const [saving, setSaving] = useState(false);
  const [saveError, setSaveError] = useState<string | null>(null);

  // Permissions
  const [permissions, setPermissions] = useState<MapPermission[]>([]);
  const [permsLoading, setPermsLoading] = useState(true);

  // Add permission
  const [addUsername, setAddUsername] = useState("");
  const [addRole, setAddRole] = useState<"editor" | "viewer">("viewer");
  const [addLoading, setAddLoading] = useState(false);
  const [addError, setAddError] = useState<string | null>(null);

  // Access requests
  const [requests, setRequests] = useState<MapAccessRequest[]>([]);
  const [reqsLoading, setReqsLoading] = useState(true);

  useEffect(() => {
    loadPermissions();
    loadRequests();
  }, [map.id]); // eslint-disable-line react-hooks/exhaustive-deps

  async function loadPermissions() {
    setPermsLoading(true);
    try {
      const perms = await api.listPermissions(map.id);
      setPermissions(perms);
    } catch {
      // silent
    } finally {
      setPermsLoading(false);
    }
  }

  async function loadRequests() {
    setReqsLoading(true);
    try {
      const reqs = await api.listAccessRequests(map.id);
      setRequests(reqs);
    } catch {
      // silent — might just not be owner
    } finally {
      setReqsLoading(false);
    }
  }

  async function handleSave(e: React.FormEvent) {
    e.preventDefault();
    const trimmed = name.trim();
    if (!trimmed) return;
    setSaving(true);
    setSaveError(null);
    try {
      const updated = await api.updateMap(map.id, {
        name: trimmed,
        public_access: publicAccess,
      });
      onUpdated(updated);
      onClose();
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err);
      setSaveError(msg.replace(/^\d+:\s*/, "").trim() || "Failed to save");
    } finally {
      setSaving(false);
    }
  }

  async function handleRemovePermission(username: string) {
    try {
      await api.updatePermission(map.id, username, null);
      setPermissions((prev) => prev.filter((p) => p.username !== username));
    } catch (err) {
      console.error("Failed to remove permission", err);
    }
  }

  async function handleAddPermission(e: React.FormEvent) {
    e.preventDefault();
    const username = addUsername.trim();
    if (!username) return;
    setAddLoading(true);
    setAddError(null);
    try {
      await api.updatePermission(map.id, username, addRole as MapRole);
      setAddUsername("");
      await loadPermissions();
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err);
      setAddError(msg.replace(/^\d+:\s*/, "").trim() || "Failed to add user");
    } finally {
      setAddLoading(false);
    }
  }

  async function handleResolveRequest(
    requestId: string,
    action: "approve" | "deny",
  ) {
    try {
      await api.resolveAccessRequest(map.id, requestId, action);
      setRequests((prev) => prev.filter((r) => r.id !== requestId));
      if (action === "approve") {
        await loadPermissions();
      }
    } catch (err) {
      console.error("Failed to resolve request", err);
    }
  }

  function handleKeyDown(e: React.KeyboardEvent) {
    if (e.key === "Escape") onClose();
  }

  const nonOwnerPerms = permissions.filter((p) => p.role !== "owner");

  return (
    <div className="modal-backdrop" onClick={onClose} onKeyDown={handleKeyDown}>
      <div
        className="modal edit-map-modal"
        onClick={(e) => e.stopPropagation()}
      >
        <div className="modal-header">
          <h2>Edit Map</h2>
          <button className="modal-close" onClick={onClose} aria-label="Close">
            ✕
          </button>
        </div>

        {/* ── Map settings ── */}
        <form onSubmit={handleSave} className="edit-map-form">
          <label className="field-label">
            Map Name
            <input
              type="text"
              value={name}
              onChange={(e) => setName(e.target.value)}
              maxLength={60}
              required
            />
          </label>

          <fieldset className="public-access-fieldset">
            <legend>Visibility</legend>

            <label className="radio-option">
              <input
                type="radio"
                name="edit_public_access"
                value="private"
                checked={publicAccess === "private"}
                onChange={() => setPublicAccess("private")}
              />
              <span className="radio-label">
                <strong>Private</strong>
                <span className="radio-hint">Only you and invited users</span>
              </span>
            </label>

            <label className="radio-option">
              <input
                type="radio"
                name="edit_public_access"
                value="public_view"
                checked={publicAccess === "public_view"}
                onChange={() => setPublicAccess("public_view")}
              />
              <span className="radio-label">
                <strong>Public – View Only</strong>
                <span className="radio-hint">
                  Anyone with the link can view
                </span>
              </span>
            </label>

            <label className="radio-option">
              <input
                type="radio"
                name="edit_public_access"
                value="public_edit"
                checked={publicAccess === "public_edit"}
                onChange={() => setPublicAccess("public_edit")}
              />
              <span className="radio-label">
                <strong>Public – View &amp; Edit</strong>
                <span className="radio-hint">
                  Anyone with the link can view and edit
                </span>
              </span>
            </label>
          </fieldset>

          {saveError && <p className="form-error">{saveError}</p>}

          <div className="modal-actions">
            <button type="button" className="btn-secondary" onClick={onClose}>
              Cancel
            </button>
            <button
              type="submit"
              className="btn-primary"
              disabled={!name.trim() || saving}
            >
              {saving ? "Saving…" : "Save Changes"}
            </button>
          </div>
        </form>

        {/* ── Permissions ── */}
        <section className="edit-section">
          <h3>Permissions</h3>

          {permsLoading ? (
            <p className="edit-loading">Loading…</p>
          ) : (
            <div className="perm-list">
              {permissions.map((p) => (
                <div key={p.user_id} className="perm-row">
                  <span className="perm-username">{p.username}</span>
                  <span className={`perm-role-badge role-${p.role}`}>
                    {p.role}
                  </span>
                  {p.role !== "owner" && (
                    <button
                      className="perm-remove"
                      onClick={() => handleRemovePermission(p.username)}
                      title={`Remove ${p.username}`}
                    >
                      ✕
                    </button>
                  )}
                </div>
              ))}
              {nonOwnerPerms.length === 0 &&
                permissions.filter((p) => p.role === "owner").length > 0 && (
                  <p className="perm-empty">No editors or viewers yet</p>
                )}
            </div>
          )}

          {/* Add user */}
          <form className="add-perm-form" onSubmit={handleAddPermission}>
            <input
              type="text"
              placeholder="Username…"
              value={addUsername}
              onChange={(e) => setAddUsername(e.target.value)}
              className="add-perm-input"
            />
            <select
              value={addRole}
              onChange={(e) =>
                setAddRole(e.target.value as "editor" | "viewer")
              }
              className="add-perm-role"
            >
              <option value="viewer">Viewer</option>
              <option value="editor">Editor</option>
            </select>
            <button
              type="submit"
              className="btn-primary btn-sm"
              disabled={!addUsername.trim() || addLoading}
            >
              {addLoading ? "…" : "Add"}
            </button>
          </form>
          {addError && (
            <p className="form-error" style={{ marginTop: "0.4rem" }}>
              {addError}
            </p>
          )}
        </section>

        {/* ── Access Requests ── */}
        {!reqsLoading && requests.length > 0 && (
          <section className="edit-section">
            <h3>Pending Access Requests</h3>
            <div className="req-list">
              {requests.map((r) => (
                <div key={r.id} className="req-row">
                  <span className="req-username">{r.username}</span>
                  <span className={`perm-role-badge role-${r.requested_role}`}>
                    {r.requested_role}
                  </span>
                  <div className="req-actions">
                    <button
                      className="btn-approve"
                      onClick={() => handleResolveRequest(r.id, "approve")}
                    >
                      ✓ Approve
                    </button>
                    <button
                      className="btn-deny"
                      onClick={() => handleResolveRequest(r.id, "deny")}
                    >
                      ✕ Deny
                    </button>
                  </div>
                </div>
              ))}
            </div>
          </section>
        )}
      </div>
    </div>
  );
}
