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

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

const mockRouterVisit = vi.fn();
const mockApiDelete = vi.fn().mockResolvedValue({});

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: (...args: any[]) => mockRouterVisit(...args),
    },
    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('@tanstack/react-query', () => ({
    useQuery: vi.fn(() => ({
        data: undefined,
        isLoading: false,
        isError: false,
        refetch: vi.fn(),
    })),
    useQueryClient: vi.fn(() => ({
        invalidateQueries: vi.fn(),
        setQueryData: vi.fn(),
    })),
    keepPreviousData: undefined,
}));

vi.mock('@/lib/api', () => ({
    api: {
        get: vi.fn(),
        post: vi.fn(),
        put: vi.fn(),
        patch: vi.fn(),
        delete: (...args: any[]) => mockApiDelete(...args),
    },
}));

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

// ── Sample data ────────────────────────────────────────────────────────────────

const baseUser = {
    id: '019efe4a-9d05-7265-8fa2-21b7c3d107dd',
    name: 'Alice Kamau',
    email: 'alice@example.com',
    phone: '+254700000001',
    status: 'active' as const,
    job_title: 'Senior Engineer',
    department: 'Engineering',
    timezone: 'Africa/Nairobi',
    force_password_reset: false,
    last_login_at: '2024-05-01T10:00:00Z',
    email_verified_at: '2023-01-20T08:00:00Z',
    created_at: '2023-01-15T08:00:00Z',
    avatar_url: null,
    role: 'super_admin',
    invited_by: null,
};

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

describe('UsersShow', () => {
    it('renders inside AdminLayout without crashing', () => {
        render(<UsersShow user={baseUser} />);
        expect(screen.getByTestId('admin-layout')).toBeInTheDocument();
    });

    it('sets the page <title> to the user name', () => {
        render(<UsersShow user={baseUser} />);
        expect(document.querySelector('title')).toHaveTextContent(
            'Alice Kamau',
        );
    });

    it('renders the user name as the main heading', () => {
        render(<UsersShow user={baseUser} />);
        expect(
            screen.getByRole('heading', { name: 'Alice Kamau' }),
        ).toBeInTheDocument();
    });

    it('renders the "Active" status badge', () => {
        render(<UsersShow user={baseUser} />);
        // Status label appears in both profile hero and overview tab
        const statusBadges = screen.getAllByText('Active');
        expect(statusBadges.length).toBeGreaterThanOrEqual(1);
    });

    it('renders the user role badge', () => {
        render(<UsersShow user={baseUser} />);
        // role appears in the hero and the permissions tab
        const roleBadges = screen.getAllByText('super_admin');
        expect(roleBadges.length).toBeGreaterThanOrEqual(1);
    });

    it('renders user email in the contact sidebar field', () => {
        render(<UsersShow user={baseUser} />);
        // email appears in sidebar contact section and overview contact card
        const emailEls = screen.getAllByText('alice@example.com');
        expect(emailEls.length).toBeGreaterThanOrEqual(1);
    });

    it('renders the user timezone', () => {
        render(<UsersShow user={baseUser} />);
        const tzEls = screen.getAllByText('Africa/Nairobi');
        expect(tzEls.length).toBeGreaterThanOrEqual(1);
    });

    it('renders job title and department in the hero subtitle', () => {
        render(<UsersShow user={baseUser} />);
        // "Senior Engineer · Engineering" appears as subtitle
        expect(
            screen.getByText('Senior Engineer · Engineering'),
        ).toBeInTheDocument();
    });

    it('renders the "Edit User" button', () => {
        render(<UsersShow user={baseUser} />);
        expect(
            screen.getByRole('button', { name: /edit user/i }),
        ).toBeInTheDocument();
    });

    it('navigates to edit page when "Edit User" button is clicked', async () => {
        const user = userEvent.setup();
        render(<UsersShow user={baseUser} />);
        await user.click(screen.getByRole('button', { name: /edit user/i }));
        expect(mockRouterVisit).toHaveBeenCalledWith(
            `/admin/users/${baseUser.id}/edit`,
        );
    });

    it('renders the overview, security, and permissions tabs', () => {
        render(<UsersShow user={baseUser} />);
        expect(
            screen.getByRole('tab', { name: /overview/i }),
        ).toBeInTheDocument();
        expect(
            screen.getByRole('tab', { name: /security/i }),
        ).toBeInTheDocument();
        expect(
            screen.getByRole('tab', { name: /permissions/i }),
        ).toBeInTheDocument();
    });

    it('shows "Suspended" status for a suspended user', () => {
        const suspendedUser = { ...baseUser, status: 'suspended' as const };
        render(<UsersShow user={suspendedUser} />);
        const suspendedLabels = screen.getAllByText('Suspended');
        expect(suspendedLabels.length).toBeGreaterThanOrEqual(1);
    });

    it('shows "No phone on file" when phone is null', () => {
        const noPhoneUser = { ...baseUser, phone: null };
        render(<UsersShow user={noPhoneUser} />);
        expect(screen.getByText('No phone on file')).toBeInTheDocument();
    });

    it('shows "Password reset required" badge when force_password_reset is true', () => {
        const forceResetUser = { ...baseUser, force_password_reset: true };
        render(<UsersShow user={forceResetUser} />);
        expect(screen.getByText('Password reset required')).toBeInTheDocument();
    });

    it('shows "Invited by" section when invited_by is present', () => {
        const userWithInvite = {
            ...baseUser,
            invited_by: {
                id: '029efe4a-9d05-7265-8fa2-21b7c3d107ee',
                name: 'Bob Odhiambo',
                email: 'bob@example.com',
            },
        };
        render(<UsersShow user={userWithInvite} />);
        expect(screen.getByText('Bob Odhiambo')).toBeInTheDocument();
        expect(screen.getByText('bob@example.com')).toBeInTheDocument();
    });
});
