"use client";

import Link from "next/link";
import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/react";
import { MoreVertical, Star } from "lucide-react";
import {
  formatMoney,
  formatUpdatedAgo,
  statusDisplay,
  type FolderWire,
  type PortfolioWire,
  type StatusTone,
} from "@/app/lib/portfolioHomeView";

const PILL_TONES: Record<StatusTone, string> = {
  early: "bg-slate-100 text-slate-600",
  tender: "bg-indigo-100 text-indigo-800",
  underway: "bg-blue-100 text-blue-800",
  ontrack: "bg-green-100 text-green-800",
  delayed: "bg-amber-100 text-amber-800",
  atrisk: "bg-red-100 text-red-800",
  done: "bg-emerald-100 text-emerald-900",
  review: "bg-yellow-100 text-yellow-800",
};

export type CardActions = {
  isStarred: (portfolioId: string) => boolean;
  folderIdOf: (portfolioId: string) => string | null;
  onToggleStar: (portfolio: PortfolioWire) => void;
  onMoveToFolder: (portfolio: PortfolioWire, folderId: string | null) => void;
  folders: FolderWire[];
};

function StatusPill({ status }: { status: string }) {
  const display = statusDisplay(status);
  return (
    <span
      className={`inline-flex items-center gap-1.5 whitespace-nowrap rounded-full px-2.5 py-0.5 text-xs font-semibold ${PILL_TONES[display.tone]}`}
    >
      <span className="h-1.5 w-1.5 rounded-full bg-current" aria-hidden />
      {display.label}
    </span>
  );
}

function StarButton({
  portfolio,
  actions,
}: {
  portfolio: PortfolioWire;
  actions: CardActions;
}) {
  const starred = actions.isStarred(portfolio.id);
  return (
    <button
      type="button"
      aria-pressed={starred}
      aria-label={`${starred ? "Unstar" : "Star"} ${portfolio.name}`}
      title={starred ? "Unstar" : "Star"}
      onClick={() => actions.onToggleStar(portfolio)}
      className="rounded-lg p-1 text-gray-500 transition-colors hover:bg-gray-100 hover:text-brandblue focus-visible:outline focus-visible:outline-2 focus-visible:outline-brandmidblue"
    >
      <Star
        size={17}
        className={starred ? "stroke-brandblue" : ""}
        fill={starred ? "#f1bb06" : "none"}
        aria-hidden
      />
    </button>
  );
}

// Headless UI Menu: the anchor prop portals the panel to the top layer, so
// the list view's scroll container can't clip it; Esc, outside-click, and
// arrow-key navigation come with the primitive.
function CardMenu({
  portfolio,
  actions,
}: {
  portfolio: PortfolioWire;
  actions: CardActions;
}) {
  const currentFolderId = actions.folderIdOf(portfolio.id);
  const itemClasses =
    "flex w-full items-center justify-between gap-3 rounded-md px-2.5 py-1.5 text-left text-sm data-[focus]:bg-gray-50";
  return (
    <Menu>
      <MenuButton
        aria-label={`Actions for ${portfolio.name}`}
        className="grid place-items-center rounded-lg p-1 text-gray-500 hover:bg-gray-100 hover:text-brandblue data-[open]:bg-gray-100 data-[open]:text-brandblue"
      >
        <MoreVertical size={16} aria-hidden />
      </MenuButton>
      <MenuItems
        anchor={{ to: "bottom end", gap: 4 }}
        className="z-20 min-w-[160px] rounded-lg border border-gray-200 bg-white p-1 shadow-md focus:outline-none"
      >
        <div className="px-2.5 py-1 text-[11px] font-semibold text-gray-500">
          Move to folder
        </div>
        {actions.folders.map((folder) => (
          <MenuItem key={folder.id}>
            <button
              type="button"
              onClick={() => actions.onMoveToFolder(portfolio, folder.id)}
              className={itemClasses}
            >
              <span className="truncate">{folder.name}</span>
              {currentFolderId === folder.id && (
                <span className="text-brandmidblue" aria-hidden>✓</span>
              )}
            </button>
          </MenuItem>
        ))}
        <MenuItem>
          <button
            type="button"
            onClick={() => actions.onMoveToFolder(portfolio, null)}
            className={itemClasses}
          >
            No folder
            {currentFolderId === null && (
              <span className="text-brandmidblue" aria-hidden>✓</span>
            )}
          </button>
        </MenuItem>
      </MenuItems>
    </Menu>
  );
}

function BudgetLine({ portfolio }: { portfolio: PortfolioWire }) {
  const { budget, cost } = portfolio;
  if (!budget) {
    return <div className="text-[13px] text-gray-500">No budget set</div>;
  }
  const pct = cost != null ? Math.round((100 * cost) / budget) : null;
  const over = cost != null && cost > budget;
  return (
    <div className="text-[13px]">
      <div className="mb-1 flex justify-between text-gray-500">
        {cost != null ? (
          <>
            <span>
              <span className="font-semibold text-gray-900 tabular-nums">
                {formatMoney(cost)}
              </span>{" "}
              of <span className="tabular-nums">{formatMoney(budget)}</span>{" "}
              budget
            </span>
            <span
              className={`tabular-nums ${over ? "font-semibold text-red-700" : ""}`}
            >
              {pct}%{over ? " over" : ""}
            </span>
          </>
        ) : (
          <>
            <span>
              Budget{" "}
              <span className="font-semibold text-gray-900 tabular-nums">
                {formatMoney(budget)}
              </span>
            </span>
            <span>no spend yet</span>
          </>
        )}
      </div>
      <div className="h-1 overflow-hidden rounded-full bg-gray-200">
        <div
          className={`h-full rounded-full ${over ? "bg-red-700" : "bg-brandmidblue"}`}
          style={{ width: `${Math.min(100, pct ?? 0)}%` }}
        />
      </div>
    </div>
  );
}

export function PortfolioGridCard({
  portfolio,
  actions,
  folderName,
}: {
  portfolio: PortfolioWire;
  actions: CardActions;
  folderName?: string | null;
}) {
  return (
    <article
      draggable
      onDragStart={(e) => {
        e.dataTransfer.setData("application/x-portfolio", portfolio.id);
        e.dataTransfer.effectAllowed = "move";
      }}
      className="flex flex-col gap-2.5 rounded-xl border border-[#e2e7ee] bg-white p-4 transition-colors hover:border-[#c3ccd8]"
    >
      <div className="flex items-start justify-between gap-2">
        <Link
          href={`/portfolio/${portfolio.id}`}
          className="text-[17px] font-semibold leading-snug text-gray-900 hover:text-brandmidblue hover:underline hover:underline-offset-2"
        >
          {portfolio.name}
        </Link>
        <StarButton portfolio={portfolio} actions={actions} />
      </div>
      <div className="flex flex-wrap items-center gap-x-3 gap-y-1.5 text-[13px] text-gray-500">
        <StatusPill status={portfolio.status} />
        <span className="font-medium text-gray-900">
          {portfolio.goal === "None" ? "No goal set" : portfolio.goal}
        </span>
        {portfolio.numberOfProperties != null && (
          <span>
            <span className="tabular-nums">
              {portfolio.numberOfProperties.toLocaleString()}
            </span>{" "}
            properties
          </span>
        )}
      </div>
      <BudgetLine portfolio={portfolio} />
      <div className="flex items-center justify-between text-xs text-gray-500">
        <span>
          {folderName ? `${folderName} · ` : ""}
          Updated {formatUpdatedAgo(portfolio.updatedAt, new Date())}
        </span>
        <CardMenu portfolio={portfolio} actions={actions} />
      </div>
    </article>
  );
}

export function PortfolioTable({
  portfolios,
  actions,
  folderNameOf,
}: {
  portfolios: PortfolioWire[];
  actions: CardActions;
  folderNameOf: (portfolioId: string) => string | null;
}) {
  return (
    <div className="overflow-x-auto rounded-xl border border-[#e2e7ee] bg-white">
      <table className="w-full text-sm">
        <thead>
          <tr className="border-b border-[#e2e7ee] text-left text-[11px] font-semibold text-gray-500">
            <th scope="col" className="w-10 px-3 py-2" aria-label="Starred" />
            <th scope="col" className="px-3 py-2">Portfolio</th>
            <th scope="col" className="px-3 py-2">Status</th>
            <th scope="col" className="px-3 py-2">Goal</th>
            <th scope="col" className="px-3 py-2 text-right">Properties</th>
            <th scope="col" className="px-3 py-2">Budget</th>
            <th scope="col" className="px-3 py-2 text-right">Updated</th>
            <th scope="col" className="w-10 px-3 py-2" aria-label="Actions" />
          </tr>
        </thead>
        <tbody>
          {portfolios.map((portfolio) => (
            <tr
              key={portfolio.id}
              draggable
              onDragStart={(e) => {
                e.dataTransfer.setData("application/x-portfolio", portfolio.id);
                e.dataTransfer.effectAllowed = "move";
              }}
              className="border-b border-[#eef1f6] last:border-b-0 hover:bg-[#f8fafc]"
            >
              <td className="px-3 py-2">
                <StarButton portfolio={portfolio} actions={actions} />
              </td>
              <td className="max-w-[280px] truncate px-3 py-2">
                <Link
                  href={`/portfolio/${portfolio.id}`}
                  className="font-semibold text-gray-900 hover:text-brandmidblue hover:underline hover:underline-offset-2"
                >
                  {portfolio.name}
                </Link>
              </td>
              <td className="px-3 py-2">
                <StatusPill status={portfolio.status} />
              </td>
              <td className="max-w-[180px] truncate px-3 py-2 text-gray-700">
                {portfolio.goal === "None" ? "—" : portfolio.goal}
              </td>
              <td className="px-3 py-2 text-right tabular-nums">
                {portfolio.numberOfProperties?.toLocaleString() ?? "—"}
              </td>
              <td className="min-w-[170px] px-3 py-2">
                <BudgetLine portfolio={portfolio} />
              </td>
              <td className="whitespace-nowrap px-3 py-2 text-right text-gray-500">
                {folderNameOf(portfolio.id)
                  ? `${folderNameOf(portfolio.id)} · `
                  : ""}
                {formatUpdatedAgo(portfolio.updatedAt, new Date())}
              </td>
              <td className="px-3 py-2">
                <CardMenu portfolio={portfolio} actions={actions} />
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}
