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

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

const mockUsePage = vi.fn();
const mockUseForm = 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: vi.fn(),
    },
    usePage: () => mockUsePage(),
    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('@/lib/api', () => ({
    api: {
        get: vi.fn(),
        post: vi.fn(),
        put: vi.fn(),
        patch: vi.fn(),
        delete: vi.fn(),
        upload: vi.fn(),
    },
}));

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

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

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

// date-fns is used for format() calls — let it run real (lightweight, no network)

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

const profile = {
    id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
    name: 'Jane Adminova',
    email: 'jane@upepofinance.com',
    phone: '+254 712 345 678',
    job_title: 'Operations Lead',
    department: 'Product',
    timezone: 'Africa/Nairobi',
    avatar_url: null,
    role: 'super_admin',
    status: 'active',
    last_login_at: '2026-06-20T08:30:00.000Z',
    email_verified_at: '2025-01-15T10:00:00.000Z',
    created_at: '2025-01-01T00:00:00.000Z',
};

function makeMockForm(overrides: Record<string, any> = {}) {
    return {
        data: {
            name: profile.name,
            email: profile.email,
            phone: profile.phone ?? '',
            job_title: profile.job_title ?? '',
            department: profile.department ?? '',
            timezone: profile.timezone,
        },
        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('Profile/Index', () => {
    beforeEach(() => {
        mockUsePage.mockReturnValue({
            props: {
                auth: { adminRole: 'super_admin', adminPermissions: [] },
                flash: {},
                errors: {},
            },
        });
        mockUseForm.mockImplementation((defaults: any) =>
            makeMockForm({ data: defaults ?? {} }),
        );
    });

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

    it('sets the page title to "Profile"', () => {
        render(<ProfileIndex profile={profile} />);
        expect(document.title).toBe('Profile');
    });

    it('renders the admin name in the hero section', () => {
        render(<ProfileIndex profile={profile} />);
        // The h1 in the hero bar contains the name
        expect(
            screen.getByRole('heading', { name: 'Jane Adminova' }),
        ).toBeInTheDocument();
    });

    it('renders the admin role badge in the hero section', () => {
        render(<ProfileIndex profile={profile} />);
        // Role is rendered as a badge span in the hero
        const roleBadges = screen.getAllByText('super_admin');
        expect(roleBadges.length).toBeGreaterThan(0);
    });

    it('renders the admin status badge', () => {
        render(<ProfileIndex profile={profile} />);
        expect(screen.getByText('active')).toBeInTheDocument();
    });

    it('renders the avatar initials when no avatar_url is set', () => {
        render(<ProfileIndex profile={profile} />);
        // Initials of "Jane Adminova" → "JA"
        const initialsEls = screen.getAllByText('JA');
        expect(initialsEls.length).toBeGreaterThan(0);
    });

    it('renders the avatar <img> when avatar_url is provided', () => {
        const profileWithAvatar = {
            ...profile,
            avatar_url: 'https://cdn.example.com/avatar.jpg',
        };
        render(<ProfileIndex profile={profileWithAvatar} />);
        const imgs = screen.getAllByRole('img', { name: 'Jane Adminova' });
        expect(imgs.length).toBeGreaterThan(0);
        expect(imgs[0]).toHaveAttribute(
            'src',
            'https://cdn.example.com/avatar.jpg',
        );
    });

    it('renders the "Personal information" form section heading', () => {
        render(<ProfileIndex profile={profile} />);
        expect(screen.getByText('Personal information')).toBeInTheDocument();
    });

    it('renders the Full name field label', () => {
        render(<ProfileIndex profile={profile} />);
        expect(screen.getByText('Full name')).toBeInTheDocument();
    });

    it('renders the Email address field label', () => {
        render(<ProfileIndex profile={profile} />);
        expect(screen.getByText('Email address')).toBeInTheDocument();
    });

    it('renders the Phone field label', () => {
        render(<ProfileIndex profile={profile} />);
        expect(screen.getByText('Phone')).toBeInTheDocument();
    });

    it('renders the Timezone field label', () => {
        render(<ProfileIndex profile={profile} />);
        expect(screen.getByText('Timezone')).toBeInTheDocument();
    });

    it('renders the Work section heading', () => {
        render(<ProfileIndex profile={profile} />);
        expect(screen.getByText('Work')).toBeInTheDocument();
    });

    it('renders the Job title field label', () => {
        render(<ProfileIndex profile={profile} />);
        expect(screen.getByText('Job title')).toBeInTheDocument();
    });

    it('renders the Department field label', () => {
        render(<ProfileIndex profile={profile} />);
        expect(screen.getByText('Department')).toBeInTheDocument();
    });

    it('renders the "Save changes" submit button', () => {
        render(<ProfileIndex profile={profile} />);
        expect(
            screen.getByRole('button', { name: /save changes/i }),
        ).toBeInTheDocument();
    });

    it('disables "Save changes" button when processing is true', () => {
        mockUseForm.mockImplementation((defaults: any) =>
            makeMockForm({ data: defaults ?? {}, processing: true }),
        );
        render(<ProfileIndex profile={profile} />);
        const saveBtn = screen.getByRole('button', { name: /save changes/i });
        expect(saveBtn).toBeDisabled();
    });

    it('renders the "Change password" link to security settings', () => {
        render(<ProfileIndex profile={profile} />);
        const link = screen.getByRole('link', { name: /change password/i });
        expect(link).toHaveAttribute('href', '/admin/settings/security');
    });

    it('renders the Account meta section with Role label', () => {
        render(<ProfileIndex profile={profile} />);
        expect(screen.getByText('Role')).toBeInTheDocument();
    });

    it('renders the "Member since" meta row', () => {
        render(<ProfileIndex profile={profile} />);
        expect(screen.getByText('Member since')).toBeInTheDocument();
    });

    it('renders "Last login" meta row', () => {
        render(<ProfileIndex profile={profile} />);
        expect(screen.getByText('Last login')).toBeInTheDocument();
    });

    it('renders "Email verified" meta row', () => {
        render(<ProfileIndex profile={profile} />);
        expect(screen.getByText('Email verified')).toBeInTheDocument();
    });

    it('renders "Never" for last_login_at when null', () => {
        render(<ProfileIndex profile={{ ...profile, last_login_at: null }} />);
        expect(screen.getByText('Never')).toBeInTheDocument();
    });

    it('renders "Not verified" when email_verified_at is null', () => {
        render(
            <ProfileIndex profile={{ ...profile, email_verified_at: null }} />,
        );
        expect(screen.getByText('Not verified')).toBeInTheDocument();
    });

    it('shows success flash banner when flash.success is present', () => {
        mockUsePage.mockReturnValue({
            props: {
                auth: { adminRole: 'super_admin', adminPermissions: [] },
                flash: { success: 'Profile updated successfully.' },
                errors: {},
            },
        });
        render(<ProfileIndex profile={profile} />);
        expect(
            screen.getByText('Profile updated successfully.'),
        ).toBeInTheDocument();
    });

    it('renders an Upload button for the avatar uploader', () => {
        render(<ProfileIndex profile={profile} />);
        // When no avatar: button text is "Upload"
        const uploadBtns = screen.getAllByRole('button', { name: /upload/i });
        expect(uploadBtns.length).toBeGreaterThan(0);
    });

    it('renders a Change avatar button when avatar_url is set', () => {
        render(
            <ProfileIndex
                profile={{
                    ...profile,
                    avatar_url: 'https://cdn.example.com/a.jpg',
                }}
            />,
        );
        const changeBtns = screen.getAllByRole('button', { name: /change/i });
        expect(changeBtns.length).toBeGreaterThan(0);
    });
});
