/* eslint-disable @typescript-eslint/no-explicit-any */
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import RolesForm from '../Form';

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

const mockRouterVisit = vi.hoisted(() => 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: {
        get: vi.fn(),
        post: vi.fn(),
        put: vi.fn(),
        patch: vi.fn(),
        delete: vi.fn(),
        visit: mockRouterVisit,
    },
    usePage: vi.fn(() => ({
        props: {
            auth: { adminRole: 'super_admin', adminPermissions: [] },
            flash: {},
            errors: {},
        },
    })),
    useForm: vi.fn((defaults: any) => ({
        data: defaults ?? {},
        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(),
    })),
}));

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

vi.mock('@/lib/api', () => ({
    api: {
        get: vi.fn(),
        post: vi.fn(),
        put: vi.fn().mockResolvedValue({}),
        patch: vi.fn(),
        delete: vi.fn(),
    },
}));

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

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

const permissionCategories = [
    {
        id: 1,
        name: 'Tenants',
        permissions: [
            { id: 1, name: 'tenant.view', label: 'View tenants' },
            { id: 2, name: 'tenant.create', label: 'Create tenants' },
            { id: 3, name: 'tenant.delete', label: 'Delete tenants' },
        ],
    },
    {
        id: 2,
        name: 'Billing',
        permissions: [
            { id: 4, name: 'billing.view', label: 'View billing' },
            { id: 5, name: 'billing.manage', label: 'Manage billing' },
        ],
    },
];

const existingRole = {
    id: 2,
    name: 'billing_admin',
    description: 'Handles billing tasks',
    is_protected: false,
    permissions: ['billing.view', 'billing.manage'],
};

const protectedRole = {
    id: 1,
    name: 'super_admin',
    description: 'Full access',
    is_protected: true,
    permissions: [
        'tenant.view',
        'tenant.create',
        'tenant.delete',
        'billing.view',
        'billing.manage',
    ],
};

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

describe('Roles/Form — create mode', () => {
    beforeEach(() => {
        vi.clearAllMocks();
    });

    it('renders inside AdminLayout with "New Role" title', () => {
        render(<RolesForm permissionCategories={permissionCategories} />);
        expect(screen.getByTestId('admin-layout')).toBeInTheDocument();
        expect(screen.getByTestId('admin-layout')).toHaveAttribute(
            'data-title',
            'New Role',
        );
    });

    it('shows "New Role" heading', () => {
        render(<RolesForm permissionCategories={permissionCategories} />);
        expect(
            screen.getByRole('heading', { name: /New Role/i }),
        ).toBeInTheDocument();
    });

    it('renders role name input empty', () => {
        render(<RolesForm permissionCategories={permissionCategories} />);
        const nameInput = screen.getByPlaceholderText(/e\.g\. Billing Admin/i);
        expect(nameInput).toBeInTheDocument();
        expect(nameInput).toHaveValue('');
    });

    it('renders description textarea empty', () => {
        render(<RolesForm permissionCategories={permissionCategories} />);
        const textarea = screen.getByPlaceholderText(
            /Describe what this role is responsible for/i,
        );
        expect(textarea).toHaveValue('');
    });

    it('renders both permission categories', () => {
        render(<RolesForm permissionCategories={permissionCategories} />);
        expect(screen.getByText('Tenants')).toBeInTheDocument();
        expect(screen.getByText('Billing')).toBeInTheDocument();
    });

    it('renders checkboxes for all permissions', () => {
        render(<RolesForm permissionCategories={permissionCategories} />);
        expect(screen.getByText('View tenants')).toBeInTheDocument();
        expect(screen.getByText('Create tenants')).toBeInTheDocument();
        expect(screen.getByText('Delete tenants')).toBeInTheDocument();
        expect(screen.getByText('View billing')).toBeInTheDocument();
        expect(screen.getByText('Manage billing')).toBeInTheDocument();
    });

    it('shows permissions count as 0 of 5 selected initially', () => {
        render(<RolesForm permissionCategories={permissionCategories} />);
        expect(screen.getByText('0 of 5 selected')).toBeInTheDocument();
    });

    it('shows "Create role" submit button', () => {
        render(<RolesForm permissionCategories={permissionCategories} />);
        expect(
            screen.getByRole('button', { name: /Create role/i }),
        ).toBeInTheDocument();
    });

    it('shows Select all button when not all permissions are selected', () => {
        render(<RolesForm permissionCategories={permissionCategories} />);
        expect(
            screen.getAllByRole('button', { name: /Select all/i }).length,
        ).toBeGreaterThan(0);
    });

    it('navigates back to /admin/roles when Cancel is clicked', async () => {
        render(<RolesForm permissionCategories={permissionCategories} />);
        await userEvent.click(screen.getByRole('button', { name: /Cancel/i }));
        expect(mockRouterVisit).toHaveBeenCalledWith('/admin/roles');
    });
});

describe('Roles/Form — edit mode', () => {
    beforeEach(() => {
        vi.clearAllMocks();
    });

    it('renders "Edit Role" heading in edit mode', () => {
        render(
            <RolesForm
                role={existingRole}
                permissionCategories={permissionCategories}
            />,
        );
        expect(
            screen.getByRole('heading', { name: /Edit Role/i }),
        ).toBeInTheDocument();
    });

    it('pre-fills role name input with existing role name', () => {
        render(
            <RolesForm
                role={existingRole}
                permissionCategories={permissionCategories}
            />,
        );
        const nameInput = screen.getByPlaceholderText(/e\.g\. Billing Admin/i);
        expect(nameInput).toHaveValue('billing_admin');
    });

    it('pre-fills description textarea', () => {
        render(
            <RolesForm
                role={existingRole}
                permissionCategories={permissionCategories}
            />,
        );
        expect(
            screen.getByDisplayValue('Handles billing tasks'),
        ).toBeInTheDocument();
    });

    it('shows existing permissions as checked', () => {
        render(
            <RolesForm
                role={existingRole}
                permissionCategories={permissionCategories}
            />,
        );
        expect(screen.getByText('2 of 5 selected')).toBeInTheDocument();
    });

    it('renders "Save changes" button in edit mode', () => {
        render(
            <RolesForm
                role={existingRole}
                permissionCategories={permissionCategories}
            />,
        );
        expect(
            screen.getByRole('button', { name: /Save changes/i }),
        ).toBeInTheDocument();
    });
});

describe('Roles/Form — protected role', () => {
    it('shows Protected badge', () => {
        render(
            <RolesForm
                role={protectedRole}
                permissionCategories={permissionCategories}
            />,
        );
        expect(screen.getByText('Protected')).toBeInTheDocument();
    });

    it('disables the role name input for protected roles', () => {
        render(
            <RolesForm
                role={protectedRole}
                permissionCategories={permissionCategories}
            />,
        );
        const nameInput = screen.getByPlaceholderText(/e\.g\. Billing Admin/i);
        expect(nameInput).toBeDisabled();
    });

    it('shows super admin bypass message instead of Select all button', () => {
        render(
            <RolesForm
                role={protectedRole}
                permissionCategories={permissionCategories}
            />,
        );
        expect(
            screen.getByText(/Super admin bypasses all permission checks/i),
        ).toBeInTheDocument();
        expect(
            screen.queryByRole('button', { name: /Select all/i }),
        ).not.toBeInTheDocument();
    });
});
