import { render, screen } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';

import type { AdminBillingSubscriptionsProps } from '@/types/admin';

vi.mock('@inertiajs/react', async () => {
  const actual = await vi.importActual('@inertiajs/react');
  return {
    ...actual,
    Head: ({ title }: { title: string }) => <title>{title}</title>,
    usePage: vi.fn(() => ({
      url: '/admin/billing/subscriptions',
      props: {
        auth: { user: { name: 'Admin', email: 'admin@test.com', is_admin: true } },
        features: {
          billing: true,
          socialAuth: false,
          emailVerification: true,
          apiTokens: true,
          userSettings: true,
          notifications: false,
          admin: true,
        },
      },
    })),
    Link: ({
      children,
      href,
      ...rest
    }: {
      children: React.ReactNode;
      href: string;
      className?: string;
    }) => (
      <a href={href} {...rest}>
        {children}
      </a>
    ),
    router: {
      patch: vi.fn(),
      delete: vi.fn(),
      post: vi.fn(),
      get: vi.fn(),
      on: vi.fn(() => vi.fn()),
    },
  };
});

vi.mock('@/Components/theme/use-theme', () => ({
  useTheme: vi.fn(() => ({ theme: 'system', setTheme: vi.fn(), resolvedTheme: 'light' })),
}));

import BillingSubscriptions from './Subscriptions';

const makePagination = <T,>(data: T[]) => ({
  data,
  current_page: 1,
  per_page: 25,
  total: data.length,
  last_page: 1,
  from: data.length > 0 ? 1 : 0,
  to: data.length,
  links: [],
});

const makeSub = (overrides = {}) => ({
  id: 1,
  user_id: 5,
  user_name: 'Alice Example',
  user_email: 'alice@example.com',
  stripe_status: 'active',
  tier: 'pro',
  quantity: 1,
  trial_ends_at: null,
  ends_at: null,
  created_at: '2026-01-01T00:00:00Z',
  ...overrides,
});

const defaultProps: AdminBillingSubscriptionsProps = {
  subscriptions: makePagination([makeSub()]),
  filters: {},
  statuses: ['active', 'trialing', 'past_due', 'canceled'],
  tiers: ['pro', 'team', 'enterprise'],
};

describe('BillingSubscriptions', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('renders the Subscriptions heading', () => {
    render(<BillingSubscriptions {...defaultProps} />);
    expect(screen.getByRole('heading', { name: 'Subscriptions', level: 1 })).toBeInTheDocument();
  });

  it('renders subscriber name and email', () => {
    render(<BillingSubscriptions {...defaultProps} />);
    expect(screen.getByText('Alice Example')).toBeInTheDocument();
    expect(screen.getByText('alice@example.com')).toBeInTheDocument();
  });

  it('renders subscription tier', () => {
    render(<BillingSubscriptions {...defaultProps} />);
    expect(screen.getByText('Pro')).toBeInTheDocument();
  });

  it('renders subscription status badge', () => {
    render(<BillingSubscriptions {...defaultProps} />);
    expect(screen.getByText('active')).toBeInTheDocument();
  });

  it('shows empty state when no subscriptions', () => {
    render(
      <BillingSubscriptions
        {...defaultProps}
        subscriptions={makePagination([])}
      />,
    );
    expect(screen.getByText('No subscriptions found')).toBeInTheDocument();
  });

  it('renders Export CSV button', () => {
    render(<BillingSubscriptions {...defaultProps} />);
    expect(screen.getByRole('link', { name: /Export CSV/i })).toBeInTheDocument();
  });

  it('renders search input', () => {
    render(<BillingSubscriptions {...defaultProps} />);
    expect(
      screen.getByRole('textbox', { name: /Search subscriptions/i }),
    ).toBeInTheDocument();
  });

  it('shows trialing badge for trialing subscriptions', () => {
    render(
      <BillingSubscriptions
        {...defaultProps}
        subscriptions={makePagination([makeSub({ stripe_status: 'trialing' })])}
      />,
    );
    expect(screen.getByText('trialing')).toBeInTheDocument();
  });

  it('shows past_due badge for past-due subscriptions', () => {
    render(
      <BillingSubscriptions
        {...defaultProps}
        subscriptions={makePagination([makeSub({ stripe_status: 'past_due' })])}
      />,
    );
    expect(screen.getByText('past_due')).toBeInTheDocument();
  });
});
