/* 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 PlansIndex from '../Index';

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

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: 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().mockResolvedValue({}),
        put: vi.fn(),
        patch: vi.fn().mockResolvedValue({ is_active: false }),
        delete: vi.fn().mockResolvedValue({}),
    },
}));

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

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

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

const basePlan = {
    id: '019efe4a-9d05-7265-8fa2-21b7c3d107dd',
    slug: 'professional',
    name: 'Professional',
    description: 'Full-featured plan for growing MFIs',
    price_monthly: 149,
    price_yearly: 1490,
    currency: 'USD',
    is_active: true,
    is_public: true,
    trial_days: 14,
    sort_order: 2,
    deleted_at: null,
    subscriptions_count: 23,
    limits: {
        max_branches: 10,
        max_staff_users: 50,
        max_active_borrowers: 5000,
        max_active_loans: 2000,
    },
    sub_module_slugs: ['core', 'loans', 'savings', 'reports'],
};

const starterPlan = {
    id: '019efe4a-9d05-7265-8fa2-21b7c3d10700',
    slug: 'starter',
    name: 'Starter',
    description: 'Entry-level plan',
    price_monthly: 49,
    price_yearly: 490,
    currency: 'USD',
    is_active: true,
    is_public: true,
    trial_days: 0,
    sort_order: 1,
    deleted_at: null,
    subscriptions_count: 8,
    limits: {
        max_branches: 1,
        max_staff_users: 5,
        max_active_borrowers: null,
        max_active_loans: null,
    },
    sub_module_slugs: ['core'],
};

const freePlan = {
    id: '019efe4a-9d05-7265-8fa2-21b7c3d10701',
    slug: 'trial',
    name: 'Trial',
    description: null,
    price_monthly: 0,
    price_yearly: 0,
    currency: 'USD',
    is_active: true,
    is_public: false,
    trial_days: 30,
    sort_order: 0,
    deleted_at: null,
    subscriptions_count: 0,
    limits: {},
    sub_module_slugs: [],
};

const archivedPlan = {
    id: '019efe4a-9d05-7265-8fa2-21b7c3d10702',
    slug: 'enterprise',
    name: 'Enterprise',
    description: 'Large organisations',
    price_monthly: 499,
    price_yearly: 4990,
    currency: 'USD',
    is_active: false,
    is_public: false,
    trial_days: 0,
    sort_order: 3,
    deleted_at: '2024-06-01T00:00:00Z',
    subscriptions_count: 0,
    limits: { max_branches: null, max_staff_users: null },
    sub_module_slugs: [],
};

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

describe('Plans/Index', () => {
    it('renders inside AdminLayout with Plans title', () => {
        render(<PlansIndex plans={[]} />);
        expect(screen.getByTestId('admin-layout')).toBeInTheDocument();
        expect(screen.getByTestId('admin-layout')).toHaveAttribute(
            'data-title',
            'Plans',
        );
    });

    it('renders Subscription Plans page header', () => {
        render(<PlansIndex plans={[]} />);
        expect(
            screen.getByRole('heading', { name: /Subscription Plans/i }),
        ).toBeInTheDocument();
    });

    it('renders a New Plan link', () => {
        render(<PlansIndex plans={[]} />);
        const newPlanLink = screen.getByRole('link', { name: /New Plan/i });
        expect(newPlanLink).toHaveAttribute('href', '/admin/plans/create');
    });

    it('renders plan cards for active plans', () => {
        render(<PlansIndex plans={[basePlan, starterPlan]} />);
        expect(screen.getByText('Professional')).toBeInTheDocument();
        expect(screen.getByText('Starter')).toBeInTheDocument();
    });

    it('renders plan monthly price', () => {
        render(<PlansIndex plans={[basePlan]} />);
        expect(screen.getByText('$149')).toBeInTheDocument();
        expect(screen.getByText('/mo')).toBeInTheDocument();
    });

    it('renders "Free" for zero-price plans', () => {
        render(<PlansIndex plans={[freePlan]} />);
        expect(screen.getByText('Free')).toBeInTheDocument();
    });

    it('renders sub-module count on plan card', () => {
        render(<PlansIndex plans={[basePlan]} />);
        expect(screen.getByText('4 sub-modules')).toBeInTheDocument();
    });

    it('renders tenant subscriber count on plan card', () => {
        render(<PlansIndex plans={[basePlan]} />);
        expect(screen.getByText('23 tenants')).toBeInTheDocument();
    });

    it('shows "Archived Plans" section when archived plans exist', () => {
        render(<PlansIndex plans={[basePlan, archivedPlan]} />);
        expect(screen.getByText(/Archived Plans/i)).toBeInTheDocument();
    });

    it('does not show "Archived Plans" section when no archived plans', () => {
        render(<PlansIndex plans={[basePlan, starterPlan]} />);
        expect(screen.queryByText(/Archived Plans/i)).not.toBeInTheDocument();
    });

    it('shows Archived badge on deleted plan card', () => {
        render(<PlansIndex plans={[archivedPlan]} />);
        expect(screen.getByText('Archived')).toBeInTheDocument();
    });

    it('renders Restore option in menu for archived plan', async () => {
        render(<PlansIndex plans={[archivedPlan]} />);

        // Open the action menu on the archived plan card
        const menuButtons = screen.getAllByRole('button');
        const moreBtn =
            menuButtons.find(
                (btn) => btn.querySelector('svg') !== null && !btn.textContent,
            ) ?? menuButtons[0];
        await userEvent.click(moreBtn);

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

    it('shows empty state when no active plans', () => {
        render(<PlansIndex plans={[]} />);
        expect(screen.getByText(/No active plans/i)).toBeInTheDocument();
    });

    it('renders trial badge for plans with trial days', () => {
        render(<PlansIndex plans={[basePlan]} />);
        expect(screen.getByText('14d trial')).toBeInTheDocument();
    });

    it('renders unlimited label for null limits', () => {
        render(<PlansIndex plans={[starterPlan]} />);
        expect(screen.getByText('Unlimited borrowers')).toBeInTheDocument();
        expect(screen.getByText('Unlimited loans')).toBeInTheDocument();
    });
});
