"use client";

import { useParams } from "next/navigation";
import { useCallback, useEffect, useState } from "react";

import { api } from "@/lib/api/client";
import type { components } from "@/lib/api/schema";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Input } from "@/components/ui/input";

type Member = components["schemas"]["MembershipRead"];
type Role = components["schemas"]["MembershipRole"];

const ROLES: Role[] = ["owner", "editor", "viewer"];

export default function MembersPage() {
  const { id: treeId } = useParams<{ id: string }>();
  const [members, setMembers] = useState<Member[]>([]);
  const [meId, setMeId] = useState<string | null>(null);
  const [email, setEmail] = useState("");
  const [role, setRole] = useState<Role>("viewer");
  const [msg, setMsg] = useState<string | null>(null);
  const [ready, setReady] = useState(false);

  const load = useCallback(async () => {
    const [me, mem] = await Promise.all([
      api.GET("/api/v1/users/me"),
      api.GET("/api/v1/trees/{tree_id}/members", { params: { path: { tree_id: treeId } } }),
    ]);
    setMeId(me.data?.id ?? null);
    setMembers(mem.data ?? []);
    setReady(true);
  }, [treeId]);

  useEffect(() => {
    load();
  }, [load]);

  const myRole = members.find((m) => m.user_id === meId)?.role;
  const isOwner = myRole === "owner";

  async function addMember(e: React.FormEvent) {
    e.preventDefault();
    setMsg(null);
    const { error, response } = await api.POST("/api/v1/trees/{tree_id}/members", {
      params: { path: { tree_id: treeId } },
      body: { email: email.trim(), role },
    });
    if (error) {
      setMsg(
        response.status === 404
          ? "No account on this site has that email — they need to register first."
          : response.status === 409
            ? "That person is already a member."
            : "Couldn't add that member.",
      );
      return;
    }
    setEmail("");
    load();
  }

  async function changeRole(membershipId: string, newRole: Role) {
    const { error } = await api.PATCH("/api/v1/trees/{tree_id}/members/{membership_id}", {
      params: { path: { tree_id: treeId, membership_id: membershipId } },
      body: { role: newRole },
    });
    if (error) setMsg("Couldn't change role (a tree must keep at least one owner).");
    load();
  }

  async function remove(membershipId: string) {
    const { error } = await api.DELETE("/api/v1/trees/{tree_id}/members/{membership_id}", {
      params: { path: { tree_id: treeId, membership_id: membershipId } },
    });
    if (error) setMsg("Couldn't remove (a tree must keep at least one owner).");
    load();
  }

  if (!ready) return <p className="text-[var(--muted)]">Loading…</p>;

  return (
    <div className="space-y-6">
      <div>
        <h1 className="text-2xl font-semibold">Members</h1>
        <p className="mt-1 text-sm text-[var(--muted)]">
          Who can see and edit this tree. {isOwner ? "You're the owner." : `Your role: ${myRole}.`}
        </p>
      </div>

      {isOwner && (
        <Card>
          <CardContent className="p-5">
            <form onSubmit={addMember} className="flex flex-wrap items-end gap-2">
              <label className="flex flex-col gap-1">
                <span className="text-xs text-[var(--muted)]">Add by email (must have an account)</span>
                <Input
                  className="w-72"
                  type="email"
                  placeholder="person@example.com"
                  value={email}
                  onChange={(e) => setEmail(e.target.value)}
                />
              </label>
              <select
                className="h-9 rounded-md border border-[var(--border)] bg-[var(--surface)] px-2 text-sm"
                value={role}
                onChange={(e) => setRole(e.target.value as Role)}
              >
                <option value="viewer">Viewer</option>
                <option value="editor">Editor</option>
                <option value="owner">Owner</option>
              </select>
              <Button type="submit" disabled={!email.trim()}>
                Add
              </Button>
            </form>
            {msg && <p className="mt-2 text-sm text-bronze">{msg}</p>}
          </CardContent>
        </Card>
      )}

      <Card className="overflow-hidden">
        <CardContent className="p-0">
          {members.map((m, i) => (
            <div
              key={m.id}
              className={`flex flex-wrap items-center justify-between gap-3 px-4 py-3 ${
                i > 0 ? "border-t border-[var(--border)]" : ""
              }`}
            >
              <div className="min-w-0">
                <div className="truncate font-medium">{m.display_name || m.email}</div>
                <div className="truncate text-xs text-[var(--muted)]">{m.email}</div>
              </div>
              {isOwner ? (
                <div className="flex items-center gap-2">
                  <select
                    className="h-8 rounded-md border border-[var(--border)] bg-[var(--surface)] px-2 text-sm capitalize"
                    value={m.role}
                    onChange={(e) => changeRole(m.id, e.target.value as Role)}
                  >
                    {ROLES.map((r) => (
                      <option key={r} value={r}>
                        {r}
                      </option>
                    ))}
                  </select>
                  <button
                    onClick={() => remove(m.id)}
                    className="text-[var(--muted)] hover:text-bronze"
                    aria-label="Remove member"
                    title="Remove member"
                  >
                    ×
                  </button>
                </div>
              ) : (
                <span className="text-sm capitalize text-[var(--muted)]">{m.role}</span>
              )}
            </div>
          ))}
        </CardContent>
      </Card>
    </div>
  );
}
