import { useEffect, useState } from "react";
import {
  api,
  type DocumentCategory,
  type Entity,
  type PortalDocument,
  type User,
} from "../api";
import { categoryLabel, formatBytes, formatDate } from "../format";

const CATEGORIES: DocumentCategory[] = ["statement", "k1", "capital_account", "tax", "other"];

export default function FundAdminHome() {
  const [entities, setEntities] = useState<Entity[]>([]);
  const [error, setError] = useState("");
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    api
      .listEntities()
      .then(setEntities)
      .catch((e) => setError(e.message))
      .finally(() => setLoading(false));
  }, []);

  if (loading) return <p className="text-gray-500 text-sm">Loading…</p>;
  if (error) return <p className="text-red-600 text-sm">{error}</p>;
  if (entities.length === 0)
    return <p className="text-gray-500 text-sm">You don't have access to any entities yet.</p>;

  return (
    <div className="space-y-8">
      {entities.map((e) => (
        <EntityDocs key={e.id} entity={e} />
      ))}
    </div>
  );
}

function EntityDocs({ entity }: { entity: Entity }) {
  const [docs, setDocs] = useState<PortalDocument[]>([]);
  const [investors, setInvestors] = useState<User[]>([]);
  const [error, setError] = useState("");

  const load = () => {
    api.listDocuments({ entity_id: entity.id }).then(setDocs).catch((e) => setError(e.message));
  };
  useEffect(() => {
    load();
    api.investorsForEntity(entity.id).then(setInvestors).catch(() => {});
  }, [entity.id]);

  const investorName = (id: number | null) =>
    id == null ? "Shared (all investors)" : investors.find((i) => i.id === id)?.name ?? `Investor ${id}`;

  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>
      {error && <p className="text-sm text-red-600 mt-2">{error}</p>}

      <UploadForm entity={entity} investors={investors} onUploaded={load} setError={setError} />

      <h3 className="text-xs font-medium text-gray-500 uppercase mt-5 mb-2">Documents</h3>
      {docs.length === 0 ? (
        <p className="text-sm text-gray-400">No documents yet.</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-2 text-xs text-gray-400">· {investorName(d.investor_user_id)}</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>
      )}
    </section>
  );
}

function UploadForm({
  entity,
  investors,
  onUploaded,
  setError,
}: {
  entity: Entity;
  investors: User[];
  onUploaded: () => void;
  setError: (s: string) => void;
}) {
  const [category, setCategory] = useState<DocumentCategory>("statement");
  const [investorId, setInvestorId] = useState<number | "">("");
  const [title, setTitle] = useState("");
  const [file, setFile] = useState<File | null>(null);
  const [busy, setBusy] = useState(false);

  const submit = async () => {
    if (!file) return;
    setError("");
    setBusy(true);
    try {
      const form = new FormData();
      form.set("entity_id", String(entity.id));
      form.set("category", category);
      if (title) form.set("title", title);
      if (investorId !== "") form.set("investor_user_id", String(investorId));
      form.set("file", file);
      await api.uploadDocument(form);
      setTitle("");
      setFile(null);
      setInvestorId("");
      onUploaded();
    } catch (e: any) {
      setError(e.message || "Upload failed");
    } finally {
      setBusy(false);
    }
  };

  return (
    <div className="mt-3 bg-gray-50 border border-gray-200 rounded p-3">
      <div className="grid grid-cols-2 gap-3">
        <div>
          <label className="block text-xs text-gray-500 mb-1">Category</label>
          <select className={inputCls} value={category} onChange={(e) => setCategory(e.target.value as DocumentCategory)}>
            {CATEGORIES.map((c) => (
              <option key={c} value={c}>
                {categoryLabel(c)}
              </option>
            ))}
          </select>
        </div>
        <div>
          <label className="block text-xs text-gray-500 mb-1">Visibility</label>
          <select
            className={inputCls}
            value={investorId}
            onChange={(e) => setInvestorId(e.target.value === "" ? "" : Number(e.target.value))}
          >
            <option value="">Shared — all investors</option>
            {investors.map((u) => (
              <option key={u.id} value={u.id}>
                Private — {u.name}
              </option>
            ))}
          </select>
        </div>
        <div>
          <label className="block text-xs text-gray-500 mb-1">Title (optional)</label>
          <input className={inputCls} value={title} onChange={(e) => setTitle(e.target.value)} />
        </div>
        <div>
          <label className="block text-xs text-gray-500 mb-1">File</label>
          <input type="file" onChange={(e) => setFile(e.target.files?.[0] ?? null)} className="text-sm" />
          {file && <span className="text-xs text-gray-400 ml-2">{formatBytes(file.size)}</span>}
        </div>
      </div>
      <div className="flex justify-end mt-2">
        <button
          onClick={submit}
          disabled={busy || !file}
          className="px-3 py-1.5 bg-gray-900 text-white text-sm rounded hover:bg-gray-800 disabled:opacity-50"
        >
          {busy ? "Uploading…" : "Upload"}
        </button>
      </div>
    </div>
  );
}

const inputCls =
  "w-full px-3 py-2 border border-gray-300 rounded text-sm focus:outline-none focus:ring-2 focus:ring-orange-500 focus:border-transparent";
