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

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('@tanstack/react-query', () => ({
    useQuery: vi.fn(() => ({
        data: undefined,
        isLoading: false,
        isFetching: 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: vi.fn(),
    },
}));

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

vi.mock('@/components/admin/DataTable', () => ({
    DataTable: ({ columns, data, quickFilters }: any) => (
        <div>
            {quickFilters?.map((f: any) => (
                <button key={f.value}>{f.label}</button>
            ))}
            <table>
                <thead>
                    <tr>
                        {columns.map((c: any) => (
                            <th key={c.accessorKey ?? c.id}>{c.header}</th>
                        ))}
                    </tr>
                </thead>
                <tbody>
                    {(data ?? []).map((r: any, i: number) => (
                        <tr key={i}>
                            {columns.map((c: any, j: number) => (
                                <td key={j}>
                                    {c.cell
                                        ? c.cell({
                                              row: {
                                                  original: r,
                                                  getValue: () =>
                                                      r[c.accessorKey],
                                              },
                                          })
                                        : String(r[c.accessorKey] ?? '')}
                                </td>
                            ))}
                        </tr>
                    ))}
                </tbody>
            </table>
        </div>
    ),
}));

vi.mock('@/components/admin/PageHeader', () => ({
    default: ({ title, description }: any) => (
        <div>
            <h2>{title}</h2>
            {description && <p>{description}</p>}
        </div>
    ),
}));

vi.mock('@/components/admin/PlanBadge', () => ({
    default: ({ plan }: any) => <span data-testid="plan-badge">{plan}</span>,
}));

vi.mock('@/hooks/useDataTable', () => ({
    useDataTable: () => ({
        params: {
            page: 1,
            sort: 'created_at',
            dir: 'desc',
            search: '',
            filter: 'all',
        },
        setParams: vi.fn(),
    }),
}));

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

import { useQuery } from '@tanstack/react-query';

const SAMPLE_SUBSCRIPTIONS = [
    {
        id: 'ee000001-0000-0000-0000-000000000001',
        tenant_id: 'ff000001-0000-0000-0000-000000000001',
        tenant_name: 'Acme Corp',
        plan_slug: 'professional',
        plan_name: 'Professional',
        status: 'active',
        billing_cycle: 'monthly',
        mrr_raw: 4900,
        mrr: 'KES 4,900',
        trial_ends_at: null,
        current_period_start: '2025-06-01T00:00:00Z',
        current_period_end: '2025-07-01T00:00:00Z',
        suspended_at: null,
        canceled_at: null,
        created_at: '2024-06-01T00:00:00Z',
    },
    {
        id: 'ee000002-0000-0000-0000-000000000002',
        tenant_id: 'ff000002-0000-0000-0000-000000000002',
        tenant_name: 'Beta Ltd',
        plan_slug: 'starter',
        plan_name: 'Starter',
        status: 'trialing',
        billing_cycle: 'yearly',
        mrr_raw: 0,
        mrr: 'KES 0',
        trial_ends_at: '2025-07-01T00:00:00Z',
        current_period_start: null,
        current_period_end: null,
        suspended_at: null,
        canceled_at: null,
        created_at: '2025-06-01T00:00:00Z',
    },
];

const SAMPLE_META = {
    current_page: 1,
    last_page: 1,
    total: 2,
    per_page: 25,
    from: 1,
    to: 2,
};

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

describe('Admin/Subscriptions/Index', () => {
    it('renders inside AdminLayout without crashing', () => {
        render(<SubscriptionsIndex />);
        expect(screen.getByTestId('admin-layout')).toBeInTheDocument();
    });

    it('sets AdminLayout title to "Subscriptions"', () => {
        render(<SubscriptionsIndex />);
        expect(screen.getByTestId('admin-layout')).toHaveAttribute(
            'data-title',
            'Subscriptions',
        );
    });

    it('shows the "Subscriptions" heading', () => {
        render(<SubscriptionsIndex />);
        expect(
            screen.getByRole('heading', { name: 'Subscriptions' }),
        ).toBeInTheDocument();
    });

    it('renders column headers: Tenant, Plan, Status, Cycle, MRR, Trial / Period end, Started', () => {
        render(<SubscriptionsIndex />);
        expect(screen.getByText('Tenant')).toBeInTheDocument();
        expect(screen.getByText('Plan')).toBeInTheDocument();
        expect(screen.getByText('Status')).toBeInTheDocument();
        expect(screen.getByText('Cycle')).toBeInTheDocument();
        expect(screen.getByText('MRR')).toBeInTheDocument();
        expect(screen.getByText('Trial / Period end')).toBeInTheDocument();
        expect(screen.getByText('Started')).toBeInTheDocument();
    });

    it('renders quick filter tabs including Trial, Active, Past Due, Suspended, Canceled', () => {
        render(<SubscriptionsIndex />);
        expect(screen.getByRole('button', { name: 'All' })).toBeInTheDocument();
        expect(
            screen.getByRole('button', { name: 'Trial' }),
        ).toBeInTheDocument();
        expect(
            screen.getByRole('button', { name: 'Active' }),
        ).toBeInTheDocument();
        expect(
            screen.getByRole('button', { name: 'Past Due' }),
        ).toBeInTheDocument();
        expect(
            screen.getByRole('button', { name: 'Suspended' }),
        ).toBeInTheDocument();
        expect(
            screen.getByRole('button', { name: 'Canceled' }),
        ).toBeInTheDocument();
    });

    it('renders subscription rows when useQuery returns data', () => {
        vi.mocked(useQuery).mockReturnValueOnce({
            data: {
                data: SAMPLE_SUBSCRIPTIONS,
                meta: SAMPLE_META,
                filter_counts: {},
            },
            isLoading: false,
            isFetching: false,
        } as any);

        render(<SubscriptionsIndex />);
        expect(screen.getByText('Acme Corp')).toBeInTheDocument();
        expect(screen.getByText('Beta Ltd')).toBeInTheDocument();
    });

    it('renders plan names for subscriptions', () => {
        vi.mocked(useQuery).mockReturnValueOnce({
            data: {
                data: SAMPLE_SUBSCRIPTIONS,
                meta: SAMPLE_META,
                filter_counts: {},
            },
            isLoading: false,
            isFetching: false,
        } as any);

        render(<SubscriptionsIndex />);
        const planBadges = screen.getAllByTestId('plan-badge');
        expect(planBadges.map((b) => b.textContent)).toContain('Professional');
        expect(planBadges.map((b) => b.textContent)).toContain('Starter');
    });

    it('renders MRR values for subscriptions', () => {
        vi.mocked(useQuery).mockReturnValueOnce({
            data: {
                data: SAMPLE_SUBSCRIPTIONS,
                meta: SAMPLE_META,
                filter_counts: {},
            },
            isLoading: false,
            isFetching: false,
        } as any);

        render(<SubscriptionsIndex />);
        expect(screen.getByText('KES 4,900')).toBeInTheDocument();
    });

    it('renders billing cycle for subscriptions', () => {
        vi.mocked(useQuery).mockReturnValueOnce({
            data: {
                data: SAMPLE_SUBSCRIPTIONS,
                meta: SAMPLE_META,
                filter_counts: {},
            },
            isLoading: false,
            isFetching: false,
        } as any);

        render(<SubscriptionsIndex />);
        expect(screen.getByText('monthly')).toBeInTheDocument();
        expect(screen.getByText('yearly')).toBeInTheDocument();
    });

    it('shows an empty table when no data is returned', () => {
        vi.mocked(useQuery).mockReturnValueOnce({
            data: undefined,
            isLoading: false,
            isFetching: false,
        } as any);

        render(<SubscriptionsIndex />);
        const rows = screen.queryAllByRole('row');
        expect(rows.length).toBe(1); // only header row
    });
});
