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

import { usePage } from '@inertiajs/react';

import type { AdminFeatureFlagsIndexProps, FeatureFlagAdmin } 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/feature-flags',
      props: {
        auth: { user: { name: 'Admin', email: 'admin@test.com', admin_role: 'admin' } },
        features: {
          billing: false,
          socialAuth: false,
          emailVerification: true,
          apiTokens: true,
          userSettings: true,
          notifications: false,
          onboarding: false,
          apiDocs: false,
          twoFactor: false,
          webhooks: false,
          admin: true,
        },
        filters: {
          search: '',
          sort: 'flag',
          dir: 'asc',
          page: 1,
        },
      },
    })),
    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(),
      on: vi.fn(() => vi.fn()),
    },
  };
});

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

vi.mock('sonner', () => ({
  toast: {
    success: vi.fn(),
    error: vi.fn(),
  },
}));

import FeatureFlagsIndex from './Index';

const createFlag = (overrides: Partial<FeatureFlagAdmin> = {}): FeatureFlagAdmin => ({
  flag: 'billing',
  env_default: false,
  global_override: null,
  effective: false,
  user_override_count: 0,
  is_protected: false,
  is_route_dependent: true,
  ...overrides,
});

const defaultFilters = {
  sort: 'flag',
  dir: 'asc',
};

const defaultProps: AdminFeatureFlagsIndexProps = {
  flags: [
    createFlag({ flag: 'billing', env_default: false, effective: false }),
    createFlag({ flag: 'email_verification', env_default: true, effective: true }),
    createFlag({ flag: 'admin', env_default: false, is_protected: true }),
    createFlag({
      flag: 'notifications',
      env_default: false,
      global_override: true,
      effective: false,
      is_route_dependent: true,
    }),
  ],
  filters: defaultFilters,
};

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

  it('renders all feature flags in table', () => {
    render(<FeatureFlagsIndex {...defaultProps} />);

    expect(screen.getByText('billing')).toBeInTheDocument();
    expect(screen.getByText('email_verification')).toBeInTheDocument();
    expect(screen.getByText('admin')).toBeInTheDocument();
    expect(screen.getByText('notifications')).toBeInTheDocument();
  });

  it('shows correct effective state badges', () => {
    render(<FeatureFlagsIndex {...defaultProps} />);

    // Find the table rows and check badges
    const offBadges = screen.getAllByText('OFF');
    const onBadges = screen.getAllByText('ON');

    // We should have multiple OFF and ON badges
    expect(offBadges.length).toBeGreaterThan(0);
    expect(onBadges.length).toBeGreaterThan(0);
  });

  it('shows protected badge for admin flag', () => {
    render(<FeatureFlagsIndex {...defaultProps} />);

    expect(screen.getByText('Protected')).toBeInTheDocument();
  });

  it('disables switch for protected flags', () => {
    render(<FeatureFlagsIndex {...defaultProps} />);

    // Find all switches and check that one is disabled
    const switches = screen.getAllByRole('switch');

    // The admin flag switch should be disabled
    const disabledSwitch = switches.find((s) => s.getAttribute('disabled') !== null);
    expect(disabledSwitch).toBeDefined();
  });

  it('shows user override count', () => {
    const propsWithOverrides: AdminFeatureFlagsIndexProps = {
      flags: [createFlag({ flag: 'billing', user_override_count: 5 })],
      filters: defaultFilters,
    };

    render(<FeatureFlagsIndex {...propsWithOverrides} />);

    expect(screen.getByText('5 users')).toBeInTheDocument();
  });

  it('shows route-dependent warning when env=off but override=on', () => {
    render(<FeatureFlagsIndex {...defaultProps} />);

    // The notifications flag has env_default=false and global_override=true
    expect(screen.getByText('Route unavailable')).toBeInTheDocument();
  });

  it('renders page heading', () => {
    render(<FeatureFlagsIndex {...defaultProps} />);
    // "Feature Flags" appears in both breadcrumb and card header
    expect(screen.getAllByText('Feature Flags').length).toBeGreaterThanOrEqual(1);
  });

  it('shows empty state when no flags exist', () => {
    render(<FeatureFlagsIndex flags={[]} filters={defaultFilters} />);
    expect(screen.getByText('No feature flags found')).toBeInTheDocument();
  });

  it('shows dash badge for null global_override', () => {
    const propsWithNull: AdminFeatureFlagsIndexProps = {
      flags: [createFlag({ flag: 'api_tokens', global_override: null })],
      filters: defaultFilters,
    };
    render(<FeatureFlagsIndex {...propsWithNull} />);
    // The '—' dash is rendered for null global overrides
    expect(screen.getAllByText('—').length).toBeGreaterThanOrEqual(1);
  });

  it('shows destructive OFF badge when global_override is false', () => {
    const propsWithFalseOverride: AdminFeatureFlagsIndexProps = {
      flags: [createFlag({ flag: 'billing', global_override: false, effective: false })],
      filters: defaultFilters,
    };
    render(<FeatureFlagsIndex {...propsWithFalseOverride} />);
    // global_override=false renders as a destructive "OFF" badge
    // There are multiple OFF badges (env default and effective), but at least one exists
    expect(screen.getAllByText('OFF').length).toBeGreaterThan(0);
  });

  it('renders resolution order explanation text', () => {
    render(<FeatureFlagsIndex {...defaultProps} />);
    expect(screen.getByText('How feature flags resolve')).toBeInTheDocument();
    expect(screen.getByText(/User override/)).toBeInTheDocument();
  });

  it('shows zero user overrides without expand button for 0-count flags', () => {
    const propsZero: AdminFeatureFlagsIndexProps = {
      flags: [createFlag({ flag: 'billing', user_override_count: 0 })],
      filters: defaultFilters,
    };
    render(<FeatureFlagsIndex {...propsZero} />);
    // Flags with 0 user overrides still render a (disabled-looking) expand button
    expect(screen.queryByText('5 users')).not.toBeInTheDocument();
  });

  it('hides toggle switch and dropdown for viewer-role admin', () => {
    vi.mocked(usePage).mockReturnValueOnce({
      url: '/admin/feature-flags',
      props: {
        auth: { user: { name: 'Viewer', email: 'viewer@test.com', admin_role: 'viewer' } },
        features: {
          billing: false,
          socialAuth: false,
          emailVerification: true,
          apiTokens: true,
          userSettings: true,
          notifications: false,
          onboarding: false,
          apiDocs: false,
          twoFactor: false,
          webhooks: false,
          admin: true,
        },
        filters: { search: '', sort: 'flag', dir: 'asc', page: 1 },
      },
    } as unknown as ReturnType<typeof usePage>);

    render(<FeatureFlagsIndex {...defaultProps} />);

    // Viewer: no switches rendered
    expect(screen.queryAllByRole('switch')).toHaveLength(0);
    // Viewer: no dropdown trigger buttons for flag actions
    expect(screen.queryAllByLabelText(/Options for .* feature flag/)).toHaveLength(0);
  });

  it('shows toggle switch and dropdown for admin-role admin', () => {
    render(<FeatureFlagsIndex {...defaultProps} />);

    // admin role: switches should be present
    expect(screen.getAllByRole('switch').length).toBeGreaterThan(0);
  });
});
