"use client";

import { useEffect, useMemo, useState } from "react";
import {
  createOrganizationApi,
  normalizeOrganization,
  type Organization,
} from "athena-auth-js";
import { Badge } from "../ui/badge";
import { Button } from "../ui/button";
import { Combobox, type ComboOption } from "../ui/combobox";

type SessionOrganizationSwitcherProps = {
  activeOrganizationId: string | null;
  onSessionRefresh?: () => Promise<void> | void;
};

export function SessionOrganizationSwitcher({
  activeOrganizationId,
  onSessionRefresh,
}: SessionOrganizationSwitcherProps) {
  const api = useMemo(() => createOrganizationApi(), []);
  const [loading, setLoading] = useState(false);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [notice, setNotice] = useState<string | null>(null);
  const [organizations, setOrganizations] = useState<Organization[]>([]);
  const [selectedOrganizationId, setSelectedOrganizationId] = useState("");
  const [selectionLocked, setSelectionLocked] = useState(false);

  const options: ComboOption[] = useMemo(
    () =>
      organizations.map((org) => ({
        value: org.id,
        label: `${org.name} (${org.slug})`,
      })),
    [organizations],
  );

  const loadOrganizations = async () => {
    setLoading(true);
    setError(null);
    setNotice(null);
    const result = await api.listOrganizations();
    if (!result.ok) {
      setError(result.message || "Failed to load organizations");
      setLoading(false);
      return;
    }
    const list = Array.isArray(result.body) ? result.body : [];
    const parsed = list
      .map(normalizeOrganization)
      .filter((value): value is Organization => value !== null);
    setOrganizations(parsed);
    if (parsed.length > 0) {
      const selectedStillExists = parsed.some(
        (org) => org.id === selectedOrganizationId,
      );
      if (selectionLocked && selectedStillExists) {
        setLoading(false);
        return;
      }
      const preferred =
        (activeOrganizationId &&
          parsed.find((org) => org.id === activeOrganizationId)?.id) ||
        (selectedStillExists ? selectedOrganizationId : "") ||
        parsed[0]?.id ||
        "";
      setSelectedOrganizationId(preferred);
    }
    setLoading(false);
  };

  const setActiveOrganization = async () => {
    if (!selectedOrganizationId) return;
    setSaving(true);
    setError(null);
    setNotice(null);
    const result = await api.setActiveOrganization(selectedOrganizationId);
    if (!result.ok) {
      setError(result.message || "Failed to set active organization");
      setSaving(false);
      return;
    }
    setSelectionLocked(false);
    if (onSessionRefresh) {
      await onSessionRefresh();
    }
    await loadOrganizations();
    setNotice("Active organization updated in session.");
    setSaving(false);
  };

  useEffect(() => {
    void loadOrganizations();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    if (!activeOrganizationId) return;
    setSelectedOrganizationId(activeOrganizationId);
    setSelectionLocked(false);
  }, [activeOrganizationId]);

  return (
    <section className="grid gap-3 rounded-2xl border border-slate-200 bg-white p-5">
      <div className="flex flex-wrap items-center justify-between gap-2">
        <h3 className="text-sm font-semibold text-slate-900">Session organization context</h3>
        <div className="flex items-center gap-2">
          <Badge variant="secondary">organizations: {organizations.length}</Badge>
          <Badge variant="secondary">
            active: {activeOrganizationId || "none"}
          </Badge>
        </div>
      </div>
      <p className="text-xs text-slate-500">
        This selector writes to `/organization/set-active` so session-bound views can branch by active org.
      </p>
      <div className="grid gap-2 md:grid-cols-[1fr_auto]">
        <Combobox
          value={selectedOrganizationId}
          onChange={(value) => {
            setSelectionLocked(true);
            setSelectedOrganizationId(value);
          }}
          options={options}
          placeholder={loading ? "Loading organizations..." : "Select organization"}
        />
        <Button type="button" onClick={() => void setActiveOrganization()} disabled={saving || !selectedOrganizationId}>
          {saving ? "Saving..." : "Set active"}
        </Button>
      </div>
      {notice ? (
        <p className="rounded-md border border-emerald-200 bg-emerald-50 px-3 py-2 text-sm text-emerald-700">{notice}</p>
      ) : null}
      {error ? (
        <p className="rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">{error}</p>
      ) : null}
    </section>
  );
}
