import { useMemo, useState } from "react";
import { api, type CapitalAccount, type Entity, type PortalDocument } from "../api";
import { categoryLabel, formatDate, formatMoneyExact } from "../format";
import CapitalChart, { type CapitalPoint } from "../components/CapitalChart";

// The investor-facing portal, rendered purely from data. Used by the investor's own home
// (InvestorHome) and by the admin read-only Investor View, so both show exactly the same thing.
export default function InvestorPortalView({
  entities,
  accounts,
  docs,
}: {
  entities: Entity[];
  accounts: CapitalAccount[];
  docs: PortalDocument[];
}) {
  if (entities.length === 0) {
    return (
      <p className="text-gray-500 text-sm">
        No fund access yet.
      </p>
    );
  }

  // When this login covers several legal names (e.g. an IRA and a trust), label each block.
  const showNames = new Set(accounts.map((a) => a.investor_user_id)).size > 1;

  return (
    <div className="space-y-8">
      {entities.map((e) => (
        <FundSection
          key={e.id}
          entity={e}
          accounts={accounts.filter((a) => a.entity_id === e.id)}
          docs={docs.filter((d) => d.entity_id === e.id)}
          showNames={showNames}
        />
      ))}
    </div>
  );
}

function FundSection({
  entity,
  accounts,
  docs,
  showNames,
}: {
  entity: Entity;
  accounts: CapitalAccount[];
  docs: PortalDocument[];
  showNames: boolean;
}) {
  const byName = useMemo(() => {
    const groups = new Map<number, CapitalAccount[]>();
    for (const a of accounts) {
      const g = groups.get(a.investor_user_id) ?? [];
      g.push(a);
      groups.set(a.investor_user_id, g);
    }
    return [...groups.values()];
  }, [accounts]);

  return (
    <section className="bg-white border border-gray-200 rounded-lg p-5">
      <div className="flex items-baseline justify-between">
        <h2 className="text-lg font-semibold text-gray-900">{entity.name}</h2>
        <span className="text-xs text-gray-400 uppercase">{entity.type}</span>
      </div>

      {byName.length === 0 ? (
        <p className="mt-3 text-sm text-gray-400">No capital account statement on file yet.</p>
      ) : (
        byName.map((group, i) => (
          <CapitalBlock
            key={group[0].investor_user_id}
            accounts={group}
            label={showNames ? group[0].investor_name : null}
            divider={i > 0}
          />
        ))
      )}

      <div className="mt-5">
        <h3 className="text-xs font-medium text-gray-500 uppercase mb-2">Documents</h3>
        {docs.length === 0 ? (
          <p className="text-sm text-gray-400">No documents available.</p>
        ) : (
          <ul className="divide-y divide-gray-100 border border-gray-100 rounded">
            {docs.map((d) => (
              <li key={d.id} className="flex items-center px-3 py-2 text-sm">
                <span className="text-gray-900">{d.title}</span>
                <span className="ml-2 text-xs text-gray-400">{categoryLabel(d.category)}</span>
                <span className="ml-auto text-xs text-gray-400 mr-3">{formatDate(d.created_at)}</span>
                <a href={api.downloadUrl(d.id)} className="text-orange-600 hover:text-orange-700">
                  Download
                </a>
              </li>
            ))}
          </ul>
        )}
      </div>
    </section>
  );
}

function CapitalBlock({
  accounts,
  label,
  divider,
}: {
  accounts: CapitalAccount[];
  label: string | null;
  divider: boolean;
}) {
  // accounts arrive newest-first; history is oldest-first for the chart/table.
  const latest = accounts[0];
  const history = useMemo(
    () => [...accounts].sort((a, b) => a.as_of_date.localeCompare(b.as_of_date)),
    [accounts],
  );
  const chartPoints: CapitalPoint[] = history.map((a) => ({
    date: a.as_of_date,
    value: a.ending_balance_cents,
    paidIn: a.contributions_cents,
    distributions: a.distributions_cents,
  }));
  // Collapsed by default so the portal opens clean; the investor expands the trend per fund.
  const [showChart, setShowChart] = useState(false);

  return (
    <div className={divider ? "mt-6 pt-5 border-t border-gray-100" : "mt-3"}>
      {label && <p className="text-sm font-medium text-gray-700">{label}</p>}
      <p className="text-sm text-gray-500 mt-1">As of {formatDate(latest.as_of_date)}</p>
      <div className="grid grid-cols-2 sm:grid-cols-4 gap-4 mt-2">
        <Metric label="Commitment" value={formatMoneyExact(latest.commitment_cents)} />
        <Metric label="Paid-in" value={formatMoneyExact(latest.contributions_cents)} />
        {latest.distributions_cents > 0 && (
          <Metric label="Distributions" value={formatMoneyExact(latest.distributions_cents)} />
        )}
        {latest.distributions_cents > 0 && latest.contributions_cents > 0 && (
          <Metric
            label="DPI"
            value={(latest.distributions_cents / latest.contributions_cents).toFixed(2) + "x"}
          />
        )}
      </div>
      <p className="text-sm text-gray-500 mt-4">Current capital value</p>
      <p className="text-3xl font-semibold text-gray-900 mt-0.5">
        {formatMoneyExact(latest.ending_balance_cents)}
      </p>

      {history.length > 1 && (
        <div className="mt-5">
          <button
            type="button"
            onClick={() => setShowChart((v) => !v)}
            aria-expanded={showChart}
            className="flex items-center gap-1.5 text-xs font-medium text-gray-500 uppercase hover:text-gray-700"
          >
            <span className={`transition-transform ${showChart ? "rotate-90" : ""}`}>▸</span>
            Capital over time
            <span className="normal-case font-normal text-gray-400">
              ({history.length} quarters{showChart ? "" : " — show"})
            </span>
          </button>
          {showChart && (
          <div className="mt-3">
          <CapitalChart points={chartPoints} />
          <table className="w-full text-sm mt-4">
            <thead className="text-gray-400 text-left">
              <tr>
                <th className="py-1 font-medium">As of</th>
                <th className="py-1 font-medium text-right">Paid-in</th>
                <th className="py-1 font-medium text-right">Distributions</th>
                <th className="py-1 font-medium text-right">Ending balance</th>
              </tr>
            </thead>
            <tbody>
              {history.map((a) => (
                <tr key={a.id} className="border-t border-gray-100">
                  <td className="py-1 text-gray-600">{formatDate(a.as_of_date)}</td>
                  <td className="py-1 text-right text-gray-600">{formatMoneyExact(a.contributions_cents)}</td>
                  <td className="py-1 text-right text-gray-600">{formatMoneyExact(a.distributions_cents)}</td>
                  <td className="py-1 text-right text-gray-900">{formatMoneyExact(a.ending_balance_cents)}</td>
                </tr>
              ))}
            </tbody>
          </table>
          </div>
          )}
        </div>
      )}
    </div>
  );
}

function Metric({ label, value }: { label: string; value: string }) {
  return (
    <div>
      <p className="text-xs text-gray-400 uppercase">{label}</p>
      <p className="text-lg font-medium text-gray-900">{value}</p>
    </div>
  );
}
