import { render } from '@testing-library/react';

import type { ServiceButtonProps } from '../lib/ServiceButton';
import type { PresaveButtonsProps } from './types';

import PresaveButtons2 from './index';

// ---- ServiceButton mock: capture rendered props in a registry. ----
const serviceButtonProps: Array<ServiceButtonProps> = [];

jest.mock('../lib/ServiceButton', () => ({
  __esModule: true,
  default: (props: any) => {
    serviceButtonProps.push(props);

    return (
      <button
        data-testid={`mockServiceButton:${props.serviceType}`}
        data-href={props.href ?? ''}
        data-has-onclick={props.onClick ? 'true' : 'false'}
      />
    );
  },
}));

// ---- Heavy peripheral component/hook mocks (we just need a render path). ----
jest.mock('../lib/SectionTitle', () => ({
  __esModule: true,
  default: () => null,
}));

jest.mock('../../components/LegalGate', () => ({
  __esModule: true,
  default: () => null,
}));

jest.mock('../../components/LegalFootnote', () => ({
  __esModule: true,
  LegalFootnote: () => null,
}));

jest.mock('../../components/ItemPageDialog', () => ({
  __esModule: true,
  getItemPageDialogUrl: () => '',
}));

jest.mock('next/dynamic', () => ({
  __esModule: true,
  default: () => () => null,
}));

jest.mock('~/src/components/DialogBoxWithStages', () => ({
  __esModule: true,
  useOpenDialog: () => [false, jest.fn()],
}));

jest.mock('~/src/hooks/useHash', () => ({
  __esModule: true,
  default: () => ({
    backToBeforeFirstHash: jest.fn(),
    hasHashParam: () => false,
    setHashParam: jest.fn(),
    removeHashParam: jest.fn(),
  }),
}));

jest.mock('~/src/store/redux', () => ({
  __esModule: true,
  useSelector: () => 'US',
}));

jest.mock('../../hooks/useEmitter', () => ({
  __esModule: true,
  useEmitter: () => ({ emit: jest.fn() }),
}));

jest.mock('./useServicePresave', () => ({
  __esModule: true,
  useServicePresave: () => jest.fn(),
}));

jest.mock('~/src/lib/songwhipApi/orchard', () => ({
  __esModule: true,
  sendMarketingConsentApi: jest.fn(),
}));

jest.mock('~/src/lib/tracker/cookies', () => ({
  __esModule: true,
  getClientId: () => ({ clientId: 'test-client' }),
}));

jest.mock('~/src/lib/sentry/client', () => ({
  __esModule: true,
  reportErrorClient: jest.fn(),
}));

jest.mock('~/src/lib/privacy', () => ({
  __esModule: true,
  GUARDIAN_CONSENT_COUNTRIES: {},
  getMarketingConsentPayload: () => ({}),
  getMarketingConsentType: () => 'singleOptIn',
  isCountryRequireFunctionalEmailControl: () => false,
  isCountryWithLockedAuth: () => false,
  isMarketingConsentRequired: () => false,
}));

// ---- resolveLink mock: return predictable results based on dataPath. ----
//
// We control 'service.match' via the dataPath to simulate a URL that
// resolves to a known service vs. one that doesn't.
jest.mock('../lib', () => ({
  __esModule: true,
  resolveLink: (_layoutData: any, dataPath: string) => {
    const isMatch = dataPath.includes('serviceMatch');

    return {
      type: 'link',
      link: isMatch
        ? 'https://open.spotify.com/album/abc'
        : 'https://example.com/foo',
      text: 'Some text',
      Icon: () => null,
      icon: undefined,
      isDefault: false,
      serviceType: isMatch ? 'spotify' : 'unknown',
      service: { match: isMatch, name: 'Spotify', key: 'spotify' },
      dataPath,
    };
  },
}));

// ---- Helpers ----

const baseLayoutData = {
  item: {
    type: 'prerelease',
    pagePath: '/album/test',
    artistIds: [1],
    artistName: 'Test Artist',
  },
} as any;

const renderWithItems: (
  items: PresaveButtonsProps['items']
) => ReturnType<typeof render> = (items) =>
  render(
    <PresaveButtons2
      title="Subscribe"
      items={items}
      sectionPath="sub"
      sectionId="sub"
      sectionIndex={0}
      layoutData={baseLayoutData}
    />
  );

beforeEach(() => {
  serviceButtonProps.length = 0;
});

describe('PresaveButtons2 - link item gating', () => {
  it('gates the button (onClick, no href) when withEmailAndOptIns=true and URL resolves to a service', () => {
    renderWithItems([
      {
        type: 'link',
        dataPath: 'custom.link.serviceMatch',
        withEmailAndOptIns: true,
      },
    ]);

    expect(serviceButtonProps).toHaveLength(1);
    const props = serviceButtonProps[0];
    expect(props.onClick).toBeDefined();
    expect(props.href).toBeUndefined();
  });

  it('does NOT gate (href, no onClick) when withEmailAndOptIns=true but URL does not resolve to a service', () => {
    renderWithItems([
      {
        type: 'link',
        dataPath: 'custom.link.nonService',
        withEmailAndOptIns: true,
      },
    ]);

    expect(serviceButtonProps).toHaveLength(1);
    const props = serviceButtonProps[0];
    expect(props.href).toBe('https://example.com/foo');
    expect(props.onClick).toBeUndefined();
  });

  it('does NOT gate (href, no onClick) when withEmailAndOptIns is false/undefined', () => {
    renderWithItems([
      {
        type: 'link',
        dataPath: 'custom.link.serviceMatch',
        withEmailAndOptIns: false,
      },
      {
        type: 'link',
        dataPath: 'custom.link.serviceMatch.b',
      },
    ]);

    expect(serviceButtonProps).toHaveLength(2);

    serviceButtonProps.forEach((props) => {
      expect(props.href).toBe('https://open.spotify.com/album/abc');
      expect(props.onClick).toBeUndefined();
    });
  });
});
