/**
 * Unit tests for ContactLinks: phone/Telegram display, labels, layout.
 * Ported from webapp/js/contactHtml.test.js buildContactLinksHtml.
 */

import { describe, it, expect, beforeEach, vi } from "vitest";
import { render, screen, fireEvent, act } from "@testing-library/react";
import { ContactLinks } from "./ContactLinks";
import { TooltipProvider } from "@/components/ui/tooltip";
import { resetAppStore } from "@/test/test-utils";

function renderWithTooltip(ui: React.ReactElement) {
  return render(<TooltipProvider>{ui}</TooltipProvider>);
}

const openPhoneLinkMock = vi.fn();
const openTelegramProfileMock = vi.fn();
const triggerHapticLightMock = vi.fn();
const copyToClipboardMock = vi.fn();

vi.mock("@/lib/open-phone-link", () => ({
  openPhoneLink: (...args: unknown[]) => openPhoneLinkMock(...args),
}));
vi.mock("@/lib/telegram-link", () => ({
  openTelegramProfile: (...args: unknown[]) => openTelegramProfileMock(...args),
}));
vi.mock("@/lib/telegram-haptic", () => ({
  triggerHapticLight: () => triggerHapticLightMock(),
}));
vi.mock("@/lib/copy-to-clipboard", () => ({
  copyToClipboard: (...args: unknown[]) => copyToClipboardMock(...args),
}));

describe("ContactLinks", () => {
  beforeEach(() => {
    resetAppStore();
    openPhoneLinkMock.mockClear();
    openTelegramProfileMock.mockClear();
    triggerHapticLightMock.mockClear();
    copyToClipboardMock.mockClear();
  });

  it("returns null when phone and username are missing", () => {
    const { container } = render(
      <ContactLinks phone={null} username={null} />
    );
    expect(container.firstChild).toBeNull();
  });

  it("renders phone only with label and tel: link", () => {
    render(<ContactLinks phone="+79991234567" username={null} showLabels />);
    expect(document.querySelector('a[href^="tel:"]')).toBeInTheDocument();
    expect(screen.getByText(/Phone/i)).toBeInTheDocument();
  });

  it("displays phone formatted for Russian numbers", () => {
    render(<ContactLinks phone="79146522209" username={null} />);
    expect(screen.getByText(/\+7 914 652-22-09/)).toBeInTheDocument();
  });

  it("renders username only with label and t.me link", () => {
    render(<ContactLinks phone={null} username="alice_dev" showLabels />);
    expect(document.querySelector('a[href*="t.me"]')).toBeInTheDocument();
    expect(screen.getByText(/alice_dev/)).toBeInTheDocument();
  });

  it("renders both phone and username with labels", () => {
    render(
      <ContactLinks
        phone="+79001112233"
        username="bob"
        showLabels
      />
    );
    expect(document.querySelector('a[href^="tel:"]')).toBeInTheDocument();
    expect(document.querySelector('a[href*="t.me"]')).toBeInTheDocument();
    expect(screen.getByText(/\+7 900 111-22-33/)).toBeInTheDocument();
    expect(screen.getByText(/@bob/)).toBeInTheDocument();
  });

  it("strips leading @ from username and displays with @", () => {
    render(<ContactLinks phone={null} username="@alice" />);
    const link = document.querySelector('a[href*="t.me/alice"]');
    expect(link).toBeInTheDocument();
    expect(link?.textContent).toContain("@alice");
  });

  it("calls openPhoneLink and triggerHapticLight when phone link is clicked", () => {
    render(
      <ContactLinks phone="+79991234567" username={null} showLabels={false} />
    );
    const telLink = document.querySelector<HTMLAnchorElement>('a[href^="tel:"]');
    expect(telLink).toBeInTheDocument();

    fireEvent.click(telLink!);

    expect(openPhoneLinkMock).toHaveBeenCalledWith("+79991234567");
    expect(triggerHapticLightMock).toHaveBeenCalled();
  });

  it("calls openTelegramProfile and triggerHapticLight when Telegram link is clicked", () => {
    render(
      <ContactLinks phone={null} username="alice_dev" showLabels={false} />
    );
    const tgLink = document.querySelector<HTMLAnchorElement>('a[href*="t.me"]');
    expect(tgLink).toBeInTheDocument();

    fireEvent.click(tgLink!);

    expect(openTelegramProfileMock).toHaveBeenCalledWith("alice_dev");
    expect(triggerHapticLightMock).toHaveBeenCalled();
  });

  describe("showCopyButtons with layout block", () => {
    it("renders copy phone button with aria-label when phone is present", () => {
      renderWithTooltip(
        <ContactLinks
          phone="+79991234567"
          username={null}
          layout="block"
          showCopyButtons
        />
      );
      expect(
        screen.getByRole("button", { name: /Copy phone number|Скопировать номер/i })
      ).toBeInTheDocument();
    });

    it("renders copy Telegram button with aria-label when username is present", () => {
      renderWithTooltip(
        <ContactLinks
          phone={null}
          username="alice_dev"
          layout="block"
          showCopyButtons
        />
      );
      expect(
        screen.getByRole("button", {
          name: /Copy Telegram username|Скопировать логин Telegram/i,
        })
      ).toBeInTheDocument();
    });

    it("calls copyToClipboard with raw phone and triggerHapticLight when copy phone is clicked", async () => {
      copyToClipboardMock.mockResolvedValue(true);
      renderWithTooltip(
        <ContactLinks
          phone="+79991234567"
          username={null}
          layout="block"
          showCopyButtons
        />
      );
      const copyBtn = screen.getByRole("button", {
        name: /Copy phone number|Скопировать номер/i,
      });
      await act(async () => {
        fireEvent.click(copyBtn);
      });

      expect(copyToClipboardMock).toHaveBeenCalledWith("+79991234567");
      expect(triggerHapticLightMock).toHaveBeenCalled();
    });

    it("calls copyToClipboard with @username when copy Telegram is clicked", async () => {
      copyToClipboardMock.mockResolvedValue(true);
      renderWithTooltip(
        <ContactLinks
          phone={null}
          username="alice_dev"
          layout="block"
          showCopyButtons
        />
      );
      const copyBtn = screen.getByRole("button", {
        name: /Copy Telegram username|Скопировать логин Telegram/i,
      });
      await act(async () => {
        fireEvent.click(copyBtn);
      });

      expect(copyToClipboardMock).toHaveBeenCalledWith("@alice_dev");
      expect(triggerHapticLightMock).toHaveBeenCalled();
    });

    it("shows Copied text in tooltip after successful copy", async () => {
      copyToClipboardMock.mockResolvedValue(true);
      renderWithTooltip(
        <ContactLinks
          phone="+79991234567"
          username={null}
          layout="block"
          showCopyButtons
        />
      );
      const copyBtn = screen.getByRole("button", {
        name: /Copy phone number|Скопировать номер/i,
      });
      await act(async () => {
        fireEvent.click(copyBtn);
      });

      const tooltip = await screen.findByRole("tooltip", {
        name: /Copied|Скопировано/i,
      });
      expect(tooltip).toBeInTheDocument();
    });

    it("does not show copy buttons when showCopyButtons is false", () => {
      render(
        <ContactLinks
          phone="+79991234567"
          username="bob"
          layout="block"
          showCopyButtons={false}
        />
      );
      expect(
        screen.queryByRole("button", { name: /Copy phone number|Скопировать номер/i })
      ).not.toBeInTheDocument();
      expect(
        screen.queryByRole("button", { name: /Copy Telegram username|Скопировать логин Telegram/i })
      ).not.toBeInTheDocument();
    });
  });
});
