"use client";

import { useCallback, useEffect, useState } from "react";
import { toast } from "@/lib/toast";
import { AlertBanner, Button, Card, Input, Select } from "@/components/ui/Primitives";
import { createNoteShare, listNoteShares, revokeNoteShare, type PublicNoteShare } from "@/lib/notes-client";
import { exportNoteText, listCollaborators, removeCollaborator, shareNoteWithUser } from "@/lib/intake-client";
import { getWebAppOrigin } from "@/lib/product-config";

interface ShareDialogProps {
  noteId: string;
  workspaceId: string;
  noteTitle: string;
  onClose: () => void;
}

type CollaboratorRow = {
  id?: string;
  sharedWithUserId?: string;
  permission?: "view" | "comment" | "edit";
  createdAt?: string;
};

export function ShareDialog({ noteId, workspaceId, noteTitle, onClose }: ShareDialogProps) {
  const [tab, setTab] = useState<"link" | "user" | "text" | "native">("link");
  const [userId, setUserId] = useState("");
  const [permission, setPermission] = useState<"view" | "comment" | "edit">("view");
  const [loading, setLoading] = useState(false);
  const [publicLinks, setPublicLinks] = useState<PublicNoteShare[]>([]);
  const [collaborators, setCollaborators] = useState<CollaboratorRow[]>([]);

  const reloadSharingState = useCallback(async () => {
    const [links, collabs] = await Promise.all([
      listNoteShares(noteId, workspaceId).catch(() => ({ items: [] as PublicNoteShare[], total: 0 })),
      listCollaborators(noteId, workspaceId).catch(() => ({ items: [] as unknown[], total: 0 })),
    ]);
    setPublicLinks(links.items);
    setCollaborators(collabs.items as CollaboratorRow[]);
  }, [noteId, workspaceId]);

  useEffect(() => {
    void reloadSharingState();
  }, [reloadSharingState]);

  async function handleCopyLink() {
    setLoading(true);
    try {
      const { shareToken, expiresAt } = await createNoteShare(noteId, workspaceId);
      const url = `${getWebAppOrigin()}/share/${shareToken}`;
      await navigator.clipboard.writeText(url);
      await reloadSharingState();
      toast.success(expiresAt ? `Share link copied; expires ${new Date(expiresAt).toLocaleDateString()}` : "Share link copied");
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Failed to create share link");
    } finally {
      setLoading(false);
    }
  }

  async function handleShareWithUser() {
    if (!userId.trim()) {
      toast.error("Please enter a user ID");
      return;
    }
    setLoading(true);
    try {
      await shareNoteWithUser(noteId, workspaceId, userId.trim(), permission);
      toast.success(`Shared with ${userId.trim()}`);
      setUserId("");
      await reloadSharingState();
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Failed to share");
    } finally {
      setLoading(false);
    }
  }

  async function handleRevokeLink(shareToken: string) {
    setLoading(true);
    try {
      await revokeNoteShare(noteId, workspaceId, shareToken);
      await reloadSharingState();
      toast.success("Public link revoked");
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Failed to revoke link");
    } finally {
      setLoading(false);
    }
  }

  async function handleRemoveCollaborator(targetUserId: string) {
    setLoading(true);
    try {
      await removeCollaborator(noteId, targetUserId);
      await reloadSharingState();
      toast.success(`Access removed for ${targetUserId}`);
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Failed to remove access");
    } finally {
      setLoading(false);
    }
  }

  async function handleCopyText() {
    setLoading(true);
    try {
      const exported = await exportNoteText(noteId, workspaceId);
      await navigator.clipboard.writeText(`${exported.title}\n\n${exported.plaintext}`);
      toast.success("Note text copied — paste in email, WhatsApp, etc.");
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Failed to export");
    } finally {
      setLoading(false);
    }
  }

  async function handleNativeShare() {
    if (!navigator.share) {
      toast.error("Web Share API not supported in this browser");
      return;
    }
    setLoading(true);
    try {
      const exported = await exportNoteText(noteId, workspaceId);
      await navigator.share({
        title: noteTitle,
        text: exported.plaintext.slice(0, 500),
        url: `${getWebAppOrigin()}/notes/${noteId}`,
      });
    } catch (e) {
      if ((e as Error)?.name !== "AbortError") {
        toast.error("Share failed");
      }
    } finally {
      setLoading(false);
    }
  }

  const tabs = [
    { key: "link" as const, label: "Copy Link" },
    { key: "user" as const, label: "Share with User" },
    { key: "text" as const, label: "Copy as Text" },
    { key: "native" as const, label: "Share Sheet" },
  ];

  return (
    <div
      className="fixed inset-0 z-[1000] flex items-center justify-center bg-[color:var(--nl-overlay-scrim)]"
      onClick={(e) => {
        if (e.target === e.currentTarget) onClose();
      }}
      role="dialog"
      aria-label="Share note"
    >
      <Card padding="lg" className="grid w-[min(480px,90vw)] gap-4">
        <div className="flex items-center justify-between">
          <h2 className="m-0 text-[length:var(--nl-fs-xl)]">Share Note</h2>
          <Button
            type="button"
            onClick={onClose}
            aria-label="Close share dialog"
            variant="ghost"
            size="sm"
            className="text-[length:var(--nl-fs-xl)]"
          >
            ×
          </Button>
        </div>

        <div className="flex flex-wrap gap-2">
          {tabs.map((t) => (
            <Button
              key={t.key}
              type="button"
              onClick={() => setTab(t.key)}
              variant={tab === t.key ? "primary" : "secondary"}
              size="sm"
              aria-label={t.label}
            >
              {t.label}
            </Button>
          ))}
        </div>

        {tab === "link" && (
          <div className="grid gap-3">
            <p className="m-0 text-[color:var(--nl-text-secondary)]">
              Generate a public read-only link that expires in 30 days. Revoke links you no longer want available.
            </p>
            <Button type="button" disabled={loading} loading={loading} onClick={() => void handleCopyLink()} aria-label="Copy share link">
              Create and Copy Link
            </Button>
            {publicLinks.length === 0 ? (
              <p className="m-0 text-[length:var(--nl-fs-sm)] text-[color:var(--nl-text-secondary)]">
                No active public links.
              </p>
            ) : (
              <div className="grid gap-2">
                {publicLinks.map((link) => (
                  <AlertBanner
                    key={link.id}
                    tone="neutral"
                    className="flex flex-wrap items-center justify-between gap-3"
                  >
                    <span className="text-[length:var(--nl-fs-sm)] text-[color:var(--nl-text-secondary)]">
                      Expires {link.expiresAt ? new Date(link.expiresAt).toLocaleDateString() : "when revoked"}
                    </span>
                    <Button type="button" variant="secondary" size="sm" disabled={loading} onClick={() => void handleRevokeLink(link.shareToken)}>
                      Revoke
                    </Button>
                  </AlertBanner>
                ))}
              </div>
            )}
          </div>
        )}

        {tab === "user" && (
          <div className="grid gap-3">
            <p className="m-0 text-[color:var(--nl-text-secondary)]">
              Share directly with a NoteLett user by their ID.
            </p>
            <Input
              type="text"
              value={userId}
              onChange={(e) => setUserId(e.target.value)}
              placeholder="User ID"
              aria-label="User ID to share with"
            />
            <Select
              value={permission}
              onChange={(e) => setPermission(e.target.value as "view" | "comment" | "edit")}
              aria-label="Permission level"
              options={[
                { value: "view", label: "View only" },
                { value: "comment", label: "Can comment" },
                { value: "edit", label: "Can edit" },
              ]}
            />
            <Button type="button" disabled={loading} loading={loading} onClick={() => void handleShareWithUser()} aria-label="Share with user">
              Share
            </Button>
            {collaborators.length === 0 ? (
              <p className="m-0 text-[length:var(--nl-fs-sm)] text-[color:var(--nl-text-secondary)]">
                No direct collaborators yet.
              </p>
            ) : (
              <div className="grid gap-2">
                {collaborators.map((collaborator) => (
                  <AlertBanner
                    key={collaborator.id ?? collaborator.sharedWithUserId}
                    tone="neutral"
                    className="flex flex-wrap items-center justify-between gap-3"
                  >
                    <span className="text-[length:var(--nl-fs-sm)] text-[color:var(--nl-text-secondary)]">
                      {collaborator.sharedWithUserId} · {collaborator.permission ?? "view"}
                    </span>
                    {collaborator.sharedWithUserId ? (
                      <Button type="button" variant="secondary" size="sm" disabled={loading} onClick={() => void handleRemoveCollaborator(collaborator.sharedWithUserId!)}>
                        Remove
                      </Button>
                    ) : null}
                  </AlertBanner>
                ))}
              </div>
            )}
          </div>
        )}

        {tab === "text" && (
          <div className="grid gap-3">
            <p className="m-0 text-[color:var(--nl-text-secondary)]">
              Copy the note content as plain text — paste into email, WhatsApp, Messages, etc.
            </p>
            <Button type="button" disabled={loading} loading={loading} onClick={() => void handleCopyText()} aria-label="Copy note text">
              Copy Note Text
            </Button>
          </div>
        )}

        {tab === "native" && (
          <div className="grid gap-3">
            <p className="m-0 text-[color:var(--nl-text-secondary)]">
              Open your device&apos;s native share sheet (AirDrop, Messages, email, etc.)
            </p>
            <Button type="button" disabled={loading} loading={loading} onClick={() => void handleNativeShare()} aria-label="Open share sheet">
              Open Share Sheet
            </Button>
            {typeof navigator !== "undefined" && !navigator.share && (
              <AlertBanner tone="warning">
                Web Share API not supported in this browser.
              </AlertBanner>
            )}
          </div>
        )}
      </Card>
    </div>
  );
}
