/* eslint-disable @typescript-eslint/no-explicit-any */
import { fireEvent, render, screen } from '@testing-library/react';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import SettingsIndex from '../Index';

// ── Mocks ─────────────────────────────────────────────────────────────────────

const mockUseForm = vi.hoisted(() => vi.fn());
const mockRouter = vi.hoisted(() => ({
    get: vi.fn(),
    post: vi.fn(),
    put: vi.fn(),
    patch: vi.fn(),
    delete: vi.fn(),
    visit: vi.fn(),
}));

vi.mock('@inertiajs/react', () => ({
    Head: ({ title }: { title: string }) => <title>{title}</title>,
    Link: ({ href, children, ...rest }: any) => (
        <a href={href} {...rest}>
            {children}
        </a>
    ),
    router: mockRouter,
    usePage: vi.fn(() => ({
        props: {
            auth: { adminRole: 'super_admin', adminPermissions: [] },
            flash: {},
            errors: {},
        },
    })),
    useForm: (defaults: any) => mockUseForm(defaults),
}));

vi.mock('@/Layouts/AdminLayout', () => ({
    default: ({ children, title }: any) => (
        <div data-testid="admin-layout" data-title={title}>
            {children}
        </div>
    ),
}));

vi.mock('@/components/admin/PageHeader', () => ({
    default: ({ title, description }: any) => (
        <div data-testid="page-header">
            <h1>{title}</h1>
            {description && <p>{description}</p>}
        </div>
    ),
}));

// Mock shadcn Tabs to render all tab content simultaneously for easy testing
vi.mock('@/components/ui/tabs', () => ({
    Tabs: ({ children, value, onValueChange }: any) => (
        <div
            data-testid="tabs"
            data-value={value}
            onClick={() => onValueChange?.('billing')}
        >
            {children}
        </div>
    ),
    TabsList: ({ children }: any) => <div role="tablist">{children}</div>,
    TabsTrigger: ({ children, value }: any) => (
        <button role="tab" data-value={value}>
            {children}
        </button>
    ),
    TabsContent: ({ children, value }: any) => (
        <div data-testid={`tab-content-${value}`}>{children}</div>
    ),
}));

vi.mock('@/components/ui/button', () => ({
    Button: ({ children, disabled, type, onClick }: any) => (
        <button type={type} disabled={disabled} onClick={onClick}>
            {children}
        </button>
    ),
}));

vi.mock('@/components/ui/input', () => ({
    Input: ({ value, onChange, type, placeholder, ...rest }: any) => (
        <input
            value={value ?? ''}
            onChange={onChange}
            type={type ?? 'text'}
            placeholder={placeholder}
            {...rest}
        />
    ),
}));

vi.mock('@/components/ui/select', () => ({
    Select: ({ children, value }: any) => (
        <div data-testid="select" data-value={value}>
            {children}
        </div>
    ),
    SelectTrigger: ({ children }: any) => <div>{children}</div>,
    SelectValue: () => null,
    SelectContent: ({ children }: any) => <div>{children}</div>,
    SelectItem: ({ children, value }: any) => (
        <option value={value}>{children}</option>
    ),
}));

// ── Fixtures ──────────────────────────────────────────────────────────────────

const generalSettings = {
    app_name: 'Upepo Finance',
    support_email: 'support@upepofinance.com',
    contact_email: 'hello@upepofinance.com',
    timezone: 'Africa/Nairobi',
    default_currency: 'KES',
};

const billingSettings = {
    invoice_prefix: 'INV-',
    tax_rate: '16',
    tax_label: 'VAT',
    grace_period_days: '7',
    trial_days: '14',
};

const mailSettings = {
    from_name: 'Upepo Finance',
    from_address: 'noreply@upepofinance.com',
    reply_to: 'support@upepofinance.com',
};

const defaultProps = {
    tab: 'general' as const,
    general: generalSettings,
    billing: billingSettings,
    mail: mailSettings,
};

// ── Test helpers ──────────────────────────────────────────────────────────────

function makeMockForm(overrides: Record<string, any> = {}) {
    return {
        data: { ...generalSettings, ...billingSettings, ...mailSettings },
        setData: vi.fn(),
        post: vi.fn(),
        put: vi.fn(),
        patch: vi.fn(),
        delete: vi.fn(),
        processing: false,
        errors: {},
        reset: vi.fn(),
        transform: vi.fn().mockReturnThis(),
        ...overrides,
    };
}

// ── Tests ─────────────────────────────────────────────────────────────────────

describe('Settings/Index', () => {
    beforeEach(() => {
        mockUseForm.mockImplementation((defaults: any) =>
            makeMockForm({ data: defaults ?? {} }),
        );
        mockRouter.get.mockReset();
    });

    it('renders inside AdminLayout', () => {
        render(<SettingsIndex {...defaultProps} />);
        expect(screen.getByTestId('admin-layout')).toBeInTheDocument();
    });

    it('sets the page title to "Settings"', () => {
        render(<SettingsIndex {...defaultProps} />);
        expect(document.title).toBe('Settings');
    });

    it('renders the PageHeader with title "Settings"', () => {
        render(<SettingsIndex {...defaultProps} />);
        expect(
            screen.getByRole('heading', { name: 'Settings' }),
        ).toBeInTheDocument();
    });

    it('renders all four tab triggers: General, Billing, Mail, Security', () => {
        render(<SettingsIndex {...defaultProps} />);
        expect(
            screen.getByRole('tab', { name: /general/i }),
        ).toBeInTheDocument();
        expect(
            screen.getByRole('tab', { name: /billing/i }),
        ).toBeInTheDocument();
        expect(screen.getByRole('tab', { name: /mail/i })).toBeInTheDocument();
        expect(
            screen.getByRole('tab', { name: /security/i }),
        ).toBeInTheDocument();
    });

    it('renders General tab content panel', () => {
        render(<SettingsIndex {...defaultProps} />);
        expect(screen.getByTestId('tab-content-general')).toBeInTheDocument();
    });

    it('renders Billing tab content panel', () => {
        render(<SettingsIndex {...defaultProps} />);
        expect(screen.getByTestId('tab-content-billing')).toBeInTheDocument();
    });

    it('renders Mail tab content panel', () => {
        render(<SettingsIndex {...defaultProps} />);
        expect(screen.getByTestId('tab-content-mail')).toBeInTheDocument();
    });

    it('renders Security tab content panel', () => {
        render(<SettingsIndex {...defaultProps} />);
        expect(screen.getByTestId('tab-content-security')).toBeInTheDocument();
    });

    it('renders "Platform name" field label in the general tab', () => {
        render(<SettingsIndex {...defaultProps} />);
        expect(screen.getByText('Platform name')).toBeInTheDocument();
    });

    it('renders "Support email" field label in the general tab', () => {
        render(<SettingsIndex {...defaultProps} />);
        expect(screen.getByText('Support email')).toBeInTheDocument();
    });

    it('renders "Invoice prefix" field label in the billing tab', () => {
        render(<SettingsIndex {...defaultProps} />);
        expect(screen.getByText('Invoice prefix')).toBeInTheDocument();
    });

    it('renders "Tax rate (%)" field label in the billing tab', () => {
        render(<SettingsIndex {...defaultProps} />);
        expect(screen.getByText('Tax rate (%)')).toBeInTheDocument();
    });

    it('renders "From name" field label in the mail tab', () => {
        render(<SettingsIndex {...defaultProps} />);
        expect(screen.getByText('From name')).toBeInTheDocument();
    });

    it('renders "From address" field label in the mail tab', () => {
        render(<SettingsIndex {...defaultProps} />);
        expect(screen.getByText('From address')).toBeInTheDocument();
    });

    it('renders "Current password" field in the security tab', () => {
        render(<SettingsIndex {...defaultProps} />);
        expect(screen.getByText('Current password')).toBeInTheDocument();
    });

    it('renders save buttons for each form section', () => {
        render(<SettingsIndex {...defaultProps} />);
        expect(screen.getByText('Save general settings')).toBeInTheDocument();
        expect(screen.getByText('Save billing settings')).toBeInTheDocument();
        expect(screen.getByText('Save mail settings')).toBeInTheDocument();
        expect(screen.getByText('Update password')).toBeInTheDocument();
    });

    it('calls router.get with the correct billing tab URL when tab changes', () => {
        render(<SettingsIndex {...defaultProps} />);
        // Our mock Tabs calls onValueChange('billing') on click
        fireEvent.click(screen.getByTestId('tabs'));
        expect(mockRouter.get).toHaveBeenCalledWith(
            '/admin/settings/billing',
            {},
            { preserveScroll: true, replace: true },
        );
    });

    it('does not show flash banner when no success flash is present', () => {
        render(<SettingsIndex {...defaultProps} />);
        // CheckCircle2 icon implies the flash banner — it should not be present
        expect(
            screen.queryByRole('img', { name: /check/i }),
        ).not.toBeInTheDocument();
    });

    it('renders the SMTP/transport info note in the mail tab', () => {
        render(<SettingsIndex {...defaultProps} />);
        expect(screen.getByText('SMTP / transport')).toBeInTheDocument();
    });

    it('renders trial length field in billing tab', () => {
        render(<SettingsIndex {...defaultProps} />);
        expect(screen.getByText('Trial length (days)')).toBeInTheDocument();
    });

    it('disables save button when processing is true', () => {
        mockUseForm.mockImplementation((defaults: any) =>
            makeMockForm({ data: defaults ?? {}, processing: true }),
        );
        render(<SettingsIndex {...defaultProps} />);
        const saveButtons = screen.getAllByRole('button');
        const disabledSaves = saveButtons.filter(
            (b) => (b as HTMLButtonElement).disabled,
        );
        expect(disabledSaves.length).toBeGreaterThan(0);
    });
});
