"use client";

import { useState } from "react";
import { toast } from "sonner";
import { ArrowLeftRight, Loader2, Unlink } from "lucide-react";

import { Button } from "@/components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { ConfirmDeleteDialog } from "@/components/confirm-delete-dialog";
import { AccountAvatar } from "@/components/profile/account-avatar";
import { removeAccountLink, toggleAccount } from "@/lib/actions/account-links";
import type { LinkedAccountDTO } from "@/types/profile";

/**
 * "Linked Accounts": the other accounts this one is linked to.
 * - "Toggle": signs this browser out and back in as that account (the
 *   server verifies the link and mints a one-time switch token, so the
 *   other account's password is never needed).
 * - "Remove Link": either account in the pair can do it; confirmed first.
 */
export function LinkedAccounts({ accounts }: { accounts: LinkedAccountDTO[] }) {
  const [togglingId, setTogglingId] = useState<string | null>(null);
  const [removing, setRemoving] = useState<LinkedAccountDTO | null>(null);
  const [removingBusy, setRemovingBusy] = useState(false);

  async function handleToggle(account: LinkedAccountDTO) {
    if (togglingId) return;
    setTogglingId(account.id);
    try {
      const result = await toggleAccount(account.id);
      if (result?.url) {
        // The action already signed this browser in as the linked account;
        // navigate so the app shell re-renders for them.
        window.location.href = result.url;
        return;
      }
      toast.error(result?.error ?? "Couldn't switch to that account.");
    } catch {
      toast.error("Couldn't switch to that account. Try again.");
    } finally {
      setTogglingId(null);
    }
  }

  async function handleRemove() {
    if (!removing) return;
    const account = removing;
    setRemoving(null);
    setRemovingBusy(true);
    try {
      const result = await removeAccountLink(account.linkId);
      if (result?.error) {
        toast.error(result.error);
        return;
      }
      toast.success(`Link with ${account.email} removed.`);
    } catch {
      toast.error("Couldn't remove the link. Try again.");
    } finally {
      setRemovingBusy(false);
    }
  }

  return (
    <Card>
      <CardHeader>
        <CardTitle>Linked Accounts</CardTitle>
        <CardDescription>
          Accounts this one is linked to. Toggle signs you in as that
          account; Remove Link works from either side.
        </CardDescription>
      </CardHeader>
      <CardContent className="flex flex-col gap-3">
        {accounts.map((account) => (
          <div
            key={account.linkId}
            className="flex flex-col gap-3 rounded-lg border p-3 sm:flex-row sm:items-center"
          >
            <div className="flex min-w-0 flex-1 items-center gap-3">
              <AccountAvatar account={account} sizeClass="size-9" />
              <div className="min-w-0">
                <p className="truncate text-sm font-medium">{account.email}</p>
                {account.name && (
                  <p className="truncate text-xs text-muted-foreground">{account.name}</p>
                )}
              </div>
            </div>
            <div className="flex flex-wrap items-center gap-2">
              <Button
                variant="secondary"
                size="sm"
                onClick={() => handleToggle(account)}
                disabled={togglingId !== null}
              >
                {togglingId === account.id ? (
                  <Loader2 className="size-3.5 animate-spin" />
                ) : (
                  <ArrowLeftRight className="size-3.5" />
                )}
                {togglingId === account.id ? "Switching…" : "Toggle"}
              </Button>
              <Button
                variant="outline"
                size="sm"
                disabled={togglingId !== null}
                onClick={() => setRemoving(account)}
              >
                <Unlink className="size-3.5" />
                Remove Link
              </Button>
            </div>
          </div>
        ))}
      </CardContent>

      <ConfirmDeleteDialog
        open={removing !== null}
        onOpenChange={(open) => !removingBusy && !open && setRemoving(null)}
        title={`Remove link with ${removing?.email}?`}
        description="Either linked account can remove the link. Removing it doesn't block anything -- the other account can still send a new link request, which you can accept again."
        confirmLabel="Remove Link"
        onConfirm={handleRemove}
      />
    </Card>
  );
}
