import { useState } from "react";
import { api } from "../api";
import type { ListedMap } from "../types";
import "./MapListModal.css";
import { FaTrash } from "react-icons/fa6";

function timeAgo(date: Date): string {
  const diff = Date.now() - new Date(date).getTime();
  const minutes = Math.floor(diff / 60_000);
  if (minutes < 1) return "just now";
  if (minutes < 60) return `${minutes}m ago`;
  const hours = Math.floor(minutes / 60);
  if (hours < 24) return `${hours}h ago`;
  const days = Math.floor(hours / 24);
  if (days < 30) return `${days}d ago`;
  const months = Math.floor(days / 30);
  if (months < 12) return `${months}mo ago`;
  return `${Math.floor(months / 12)}y ago`;
}

interface Props {
  maps: ListedMap[];
  selectedMapId: string | null;
  onSelect: (id: string) => void;
  onClose: () => void;
  onMapsChange: (maps: ListedMap[]) => void;
}

/** Copy text to the clipboard; show a brief "Copied!" toast. */
function copyToClipboard(
  text: string,
  setCopied: (id: string | null) => void,
  id: string,
) {
  navigator.clipboard.writeText(text).then(() => {
    setCopied(id);
    setTimeout(() => setCopied(null), 1500);
  });
}

function accessLabel(access: string): string {
  switch (access) {
    case "public_view":
      return "Public (view)";
    case "public_edit":
      return "Public (edit)";
    default:
      return "Private";
  }
}

export default function MapListModal({
  maps,
  selectedMapId,
  onSelect,
  onClose,
  onMapsChange,
}: Props) {
  const [copiedId, setCopiedId] = useState<string | null>(null);
  const [togglingId, setTogglingId] = useState<string | null>(null);

  async function handleFavoriteToggle(e: React.MouseEvent, map: ListedMap) {
    e.stopPropagation();
    setTogglingId(map.id);
    try {
      if (map.is_favorited) {
        await api.unfavoriteMap(map.id);
      } else {
        await api.favoriteMap(map.id);
      }
      onMapsChange(
        maps.map((m) =>
          m.id === map.id ? { ...m, is_favorited: !m.is_favorited } : m,
        ),
      );
    } catch (err) {
      console.error("Failed to toggle favorite", err);
    } finally {
      setTogglingId(null);
    }
  }

  function handleCopyLink(e: React.MouseEvent, map: ListedMap) {
    e.stopPropagation();
    const link = `${window.location.origin}/map/${encodeURIComponent(map.id)}`;
    copyToClipboard(link, setCopiedId, map.id);
  }

  function handleSelect(map: ListedMap) {
    onSelect(map.id);
    onClose();
  }

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

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

        {maps.length === 0 ? (
          <p className="map-list-empty">
            No maps yet. Click "+ New Map" to create one.
          </p>
        ) : (
          <div className="map-list-scroll">
            {[...maps]
              .sort(
                (a, b) =>
                  new Date(b.updated_at).getTime() -
                  new Date(a.updated_at).getTime(),
              )
              .map((map) => (
                <div
                  key={map.id}
                  className={`map-list-row ${map.id === selectedMapId ? "active" : ""}`}
                  onClick={() => handleSelect(map)}
                  role="button"
                  tabIndex={0}
                  onKeyDown={(e) => e.key === "Enter" && handleSelect(map)}
                >
                  <div className="map-list-main">
                    <span className="map-list-name">{map.name}</span>
                    <div className="map-list-meta">
                      <span className="map-list-owner">
                        by {map.owner_username}
                      </span>
                      <span
                        className={`map-access-badge access-${map.public_access}`}
                      >
                        {accessLabel(map.public_access)}
                      </span>
                      {map.user_role && (
                        <span
                          className={`perm-role-badge role-${map.user_role}`}
                        >
                          {map.user_role}
                        </span>
                      )}
                      {map.is_favorited && !map.user_role && (
                        <span className="map-fav-badge">★ Favorited</span>
                      )}
                      <span
                        className="map-list-updated"
                        title={new Date(map.updated_at).toLocaleString()}
                      >
                        {timeAgo(map.updated_at)}
                      </span>
                    </div>
                  </div>

                  <div className="map-list-actions">
                    {/* Favorite toggle */}
                    <button
                      className={`map-action-btn fav-btn ${map.is_favorited ? "fav-active" : ""}`}
                      onClick={(e) => handleFavoriteToggle(e, map)}
                      disabled={togglingId === map.id}
                      title={
                        map.is_favorited
                          ? "Remove from favorites"
                          : "Add to favorites"
                      }
                    >
                      {map.is_favorited ? "★" : "☆"}
                    </button>

                    {/* Copy link */}
                    <button
                      className="map-action-btn copy-btn"
                      onClick={(e) => handleCopyLink(e, map)}
                      title="Copy link"
                    >
                      {copiedId === map.id ? (
                        <span className="copied-text">✓</span>
                      ) : (
                        <svg
                          width="14"
                          height="14"
                          viewBox="0 0 24 24"
                          fill="none"
                          stroke="currentColor"
                          strokeWidth="2"
                          strokeLinecap="round"
                          strokeLinejoin="round"
                        >
                          <rect
                            x="9"
                            y="9"
                            width="13"
                            height="13"
                            rx="2"
                            ry="2"
                          />
                          <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
                        </svg>
                      )}
                    </button>

                    {/* Delete map button */}
                    <button
                      className="map-action-btn delete-btn"
                      onClick={async (e) => {
                        e.stopPropagation();
                        if (
                          window.confirm(
                            "Are you sure you want to delete this map? This action cannot be undone.",
                          )
                        ) {
                          try {
                            await api.deleteMap(map.id);
                            onMapsChange(maps.filter((m) => m.id !== map.id));
                          } catch (err) {
                            console.error("Failed to delete map", err);
                          }
                        }
                      }}
                      title="Delete map"
                    >
                      <FaTrash />
                    </button>
                  </div>
                </div>
              ))}
          </div>
        )}
      </div>
    </div>
  );
}
