'use client';

import { useCallback, useEffect, useState } from 'react';
import {
  organizationApi,
  type OrganizationInvitationHistoryItemDto,
} from '@/lib/api/organization';
import {
  canShareOrganizationInviteLink,
  readOrganizationInviteLinks,
  type StoredOrganizationInviteLink,
  writeOrganizationInviteLinks,
} from '@/components/invitations/organizationInviteLinks';

export function useOrganizationInviteLinkCopy(organizationId: string | undefined) {
  const [pendingInviteLinks, setPendingInviteLinks] = useState<
    Record<string, StoredOrganizationInviteLink>
  >({});
  const [copiedId, setCopiedId] = useState<string | null>(null);
  const [copyingInvitationId, setCopyingInvitationId] = useState<string | null>(null);

  useEffect(() => {
    if (!organizationId) return;
    setPendingInviteLinks(readOrganizationInviteLinks(organizationId));
  }, [organizationId]);

  const storeInviteLink = useCallback(
    (invitationId: string, ownerEmail: string, invitationUrl: string) => {
      if (!organizationId) return;
      setPendingInviteLinks((prev) => {
        const next = {
          ...prev,
          [invitationId]: {
            invitationId,
            ownerEmail: ownerEmail.trim().toLowerCase(),
            invitationUrl,
          },
        };
        writeOrganizationInviteLinks(organizationId, next);
        return next;
      });
    },
    [organizationId],
  );

  const pruneAcceptedLinks = useCallback(
    (items: OrganizationInvitationHistoryItemDto[]) => {
      if (!organizationId) return;
      const acceptedIds = new Set(
        items.filter((item) => item.acceptedAt || item.status === 'ACTIVE').map((item) => item.id),
      );

      setPendingInviteLinks((prev) => {
        let changed = false;
        const next = { ...prev };
        for (const id of Object.keys(next)) {
          if (acceptedIds.has(id)) {
            delete next[id];
            changed = true;
          }
        }
        if (changed) {
          writeOrganizationInviteLinks(organizationId, next);
        }
        return changed ? next : prev;
      });
    },
    [organizationId],
  );

  const copyInvitationLink = useCallback(
    async (
      invitation: OrganizationInvitationHistoryItemDto,
      options?: { onRegenerated?: () => void | Promise<void> },
    ): Promise<string | null> => {
      if (!canShareOrganizationInviteLink(invitation)) return null;

      setCopyingInvitationId(invitation.id);
      try {
        let invitationUrl = pendingInviteLinks[invitation.id]?.invitationUrl;
        if (!invitationUrl || invitation.status === 'EXPIRED') {
          const res = await organizationApi.getInvitationLink(invitation.id);
          invitationUrl = res.data.invitationUrl;
          storeInviteLink(invitation.id, invitation.ownerEmail, invitationUrl);
          await options?.onRegenerated?.();
        }

        await navigator.clipboard.writeText(invitationUrl);
        setCopiedId(invitation.id);
        setTimeout(() => setCopiedId(null), 1500);
        return invitationUrl;
      } finally {
        setCopyingInvitationId(null);
      }
    },
    [pendingInviteLinks, storeInviteLink],
  );

  return {
    pendingInviteLinks,
    copiedId,
    copyingInvitationId,
    storeInviteLink,
    copyInvitationLink,
    pruneAcceptedLinks,
  };
}
