/* eslint-disable @typescript-eslint/no-explicit-any */
import type {
    ActivityItem,
    AttentionItem,
    DashboardStats,
    MonthlyData,
    PlanDistribution,
    SystemStatusItem,
    TenantRow,
} from '@/types/admin';
import { render, screen } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';
import DashboardIndex 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('@/hooks/useIsDark', () => ({
    useIsDark: vi.fn(() => false),
}));

vi.mock('@/components/admin/chart-theme', () => ({
    getChartTheme: vi.fn(() => ({
        grid: '#e5e7eb',
        tick: { fill: '#6b7280', fontSize: 11 },
        tooltip: {
            contentStyle: { background: '#fff', border: '1px solid #e5e7eb' },
            cursor: { fill: 'rgba(0,0,0,0.04)' },
        },
    })),
}));

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

vi.mock('@/components/admin/StatCard', () => ({
    default: ({ label, value, sub }: any) => (
        <div data-testid="stat-card">
            <span data-testid="stat-label">{label}</span>
            <span data-testid="stat-value">{value}</span>
            {sub && <span data-testid="stat-sub">{sub}</span>}
        </div>
    ),
}));

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

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

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

vi.mock('@/components/admin/ActivityFeed', () => ({
    default: ({ items }: any) => (
        <div data-testid="activity-feed">
            {items.map((item: ActivityItem, i: number) => (
                <div key={i} data-testid="activity-item">
                    {item.text}
                </div>
            ))}
        </div>
    ),
}));

vi.mock('recharts', () => ({
    ResponsiveContainer: ({ children }: any) => <div>{children}</div>,
    AreaChart: ({ children }: any) => <div>{children}</div>,
    BarChart: ({ children }: any) => <div>{children}</div>,
    PieChart: ({ children }: any) => <div>{children}</div>,
    Area: () => null,
    Bar: () => null,
    Pie: () => null,
    Cell: () => null,
    XAxis: () => null,
    YAxis: () => null,
    CartesianGrid: () => null,
    Tooltip: () => null,
    Legend: () => null,
}));

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

const stats: DashboardStats = {
    total_tenants: 1247,
    total_tenants_growth: '+12 this month',
    tenants_trend: { value: '1%', positive: true },
    mrr: 'USD 2.4M',
    mrr_trend: { value: '8.3%', positive: true },
    mrr_yoy: { value: '42%', positive: true },
    active_subscriptions: 983,
    subscription_rate: '78.8%',
    subs_trend: { value: '3.1%', positive: true },
    trial_conversion: '64.2%',
    trial_conversion_label: '89 of 139 completed trials',
};

const monthly: MonthlyData[] = Array.from({ length: 12 }, (_, i) => ({
    month: `M${i + 1}`,
    signups: 10 + i,
    mrr: 100_000 + i * 10_000,
}));

const recentTenants: TenantRow[] = [
    {
        id: 'tenant-1',
        name: 'Acme Corp',
        domain: 'acme.upepofinance.com',
        country: 'KE',
        owner_id: 'user-1',
        owner_name: 'Wanjiku Kamau',
        owner_email: 'wanjiku@example.com',
        plan: 'Professional',
        status: 'active',
        mrr: 'USD 15,000',
        joined: '01 Jan 2026',
    },
    {
        id: 'tenant-2',
        name: 'Beta Ltd',
        domain: null,
        country: 'NG',
        owner_id: null,
        owner_name: null,
        owner_email: null,
        plan: 'Starter',
        status: 'trial',
        mrr: 'USD 5,000',
        joined: '15 Feb 2026',
    },
];

const planDistribution: PlanDistribution[] = [
    { name: 'Enterprise', value: 45, color: '#f97316' },
    { name: 'Professional', value: 320, color: '#6366f1' },
    { name: 'Starter', value: 612, color: '#3b82f6' },
    { name: 'Free Trial', value: 270, color: '#10b981' },
];

const systemStatus: SystemStatusItem[] = [
    { label: 'API Gateway', status: 'operational', detail: '99.99% uptime' },
    { label: 'Database', status: 'operational', detail: 'Replica lag < 1s' },
    { label: 'Queue', status: 'warning', detail: '12 jobs delayed' },
];

const recentActivity: ActivityItem[] = [
    { type: 'signup', text: 'Acme Corp signed up', time: '2 min ago' },
    { type: 'upgrade', text: 'Beta Ltd upgraded to Pro', time: '1 hr ago' },
];

const attention: AttentionItem[] = [
    {
        key: 'churn',
        label: 'Churned (30d)',
        value: 3,
        sub: 'USD 1,200 MRR lost',
        href: '/admin/analytics',
    },
    {
        key: 'pending',
        label: 'Pending Tenants',
        value: 14,
        sub: 'On trial or not yet subscribed',
        href: '/admin/tenants/pending',
    },
    {
        key: 'suspended',
        label: 'Suspended Tenants',
        value: 2,
        sub: 'Suspended or canceled',
        href: '/admin/tenants/suspended',
    },
    {
        key: 'tickets',
        label: 'Open Tickets',
        value: 7,
        sub: '5 open · 2 pending',
        href: '/admin/support',
    },
];

const defaultProps = {
    stats,
    attention,
    monthly,
    recentTenants,
    planDistribution,
    systemStatus,
    recentActivity,
};

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

describe('Dashboard/Index', () => {
    it('renders inside AdminLayout', () => {
        render(<DashboardIndex {...defaultProps} />);
        expect(screen.getByTestId('admin-layout')).toBeInTheDocument();
    });

    it('sets the page title via Head', () => {
        render(<DashboardIndex {...defaultProps} />);
        expect(document.title).toBe('Admin Dashboard');
    });

    it('renders the PageHeader with correct title', () => {
        render(<DashboardIndex {...defaultProps} />);
        expect(screen.getByTestId('page-header')).toBeInTheDocument();
        expect(screen.getByText('Platform Overview')).toBeInTheDocument();
    });

    it('renders four stat cards for KPI metrics', () => {
        render(<DashboardIndex {...defaultProps} />);
        const cards = screen.getAllByTestId('stat-card');
        expect(cards).toHaveLength(4);
    });

    it('displays the total tenants value from props', () => {
        render(<DashboardIndex {...defaultProps} />);
        // toLocaleString() on 1247 → "1,247"
        expect(screen.getByText('1,247')).toBeInTheDocument();
    });

    it('displays the MRR value from props', () => {
        render(<DashboardIndex {...defaultProps} />);
        expect(screen.getByText('USD 2.4M')).toBeInTheDocument();
    });

    it('displays the active subscriptions value from props', () => {
        render(<DashboardIndex {...defaultProps} />);
        expect(screen.getByText('983')).toBeInTheDocument();
    });

    it('displays the trial conversion rate from props', () => {
        render(<DashboardIndex {...defaultProps} />);
        expect(screen.getByText('64.2%')).toBeInTheDocument();
    });

    it('renders needs-attention cards linking to their admin pages', () => {
        render(<DashboardIndex {...defaultProps} />);

        expect(
            screen.getByRole('link', { name: /churned \(30d\)/i }),
        ).toHaveAttribute('href', '/admin/analytics');
        expect(
            screen.getByRole('link', { name: /pending tenants/i }),
        ).toHaveAttribute('href', '/admin/tenants/pending');
        expect(
            screen.getByRole('link', { name: /suspended tenants/i }),
        ).toHaveAttribute('href', '/admin/tenants/suspended');
        expect(
            screen.getByRole('link', { name: /open tickets/i }),
        ).toHaveAttribute('href', '/admin/support');
        expect(screen.getByText('5 open · 2 pending')).toBeInTheDocument();
    });

    it('renders the Recent Tenants section heading', () => {
        render(<DashboardIndex {...defaultProps} />);
        expect(screen.getByText('Recent Tenants')).toBeInTheDocument();
    });

    it('renders tenant rows for each recent tenant', () => {
        render(<DashboardIndex {...defaultProps} />);
        expect(screen.getByText('Acme Corp')).toBeInTheDocument();
        expect(screen.getByText('Beta Ltd')).toBeInTheDocument();
    });

    it('renders plan badges for each recent tenant', () => {
        render(<DashboardIndex {...defaultProps} />);
        expect(screen.getAllByText('Professional').length).toBeGreaterThan(0);
        expect(screen.getAllByText('Starter').length).toBeGreaterThan(0);
    });

    it('renders tenant status badges', () => {
        render(<DashboardIndex {...defaultProps} />);
        expect(screen.getByText('active')).toBeInTheDocument();
        expect(screen.getByText('trial')).toBeInTheDocument();
    });

    it('renders Plan Distribution heading', () => {
        render(<DashboardIndex {...defaultProps} />);
        expect(screen.getByText('Plan Distribution')).toBeInTheDocument();
    });

    it('renders each plan name in the plan distribution legend', () => {
        render(<DashboardIndex {...defaultProps} />);
        expect(screen.getByText('Enterprise')).toBeInTheDocument();
        expect(screen.getByText('Free Trial')).toBeInTheDocument();
    });

    it('renders System Status heading', () => {
        render(<DashboardIndex {...defaultProps} />);
        expect(screen.getByText('System Status')).toBeInTheDocument();
    });

    it('renders a status dot and label for each system service', () => {
        render(<DashboardIndex {...defaultProps} />);
        expect(screen.getByText('API Gateway')).toBeInTheDocument();
        expect(screen.getByText('Database')).toBeInTheDocument();
        expect(screen.getByText('Queue')).toBeInTheDocument();
    });

    it('renders the activity feed with recent activity items', () => {
        render(<DashboardIndex {...defaultProps} />);
        expect(screen.getByTestId('activity-feed')).toBeInTheDocument();
        expect(screen.getByText('Acme Corp signed up')).toBeInTheDocument();
        expect(
            screen.getByText('Beta Ltd upgraded to Pro'),
        ).toBeInTheDocument();
    });

    it('renders the "View all" link pointing to /admin/tenants', () => {
        render(<DashboardIndex {...defaultProps} />);
        const link = screen.getByRole('link', { name: /view all/i });
        expect(link).toHaveAttribute('href', '/admin/tenants');
    });

    it('derives the header pill from system status (warning present)', () => {
        render(<DashboardIndex {...defaultProps} />);
        // fixture includes a 'warning' entry, so the pill must not claim all-clear
        expect(screen.getByText('Degraded Performance')).toBeInTheDocument();
    });

    it('shows the all-clear pill when every probe is operational', () => {
        render(
            <DashboardIndex
                {...defaultProps}
                systemStatus={systemStatus.map((s) => ({
                    ...s,
                    status: 'operational' as const,
                }))}
            />,
        );
        expect(screen.getByText('All Systems Operational')).toBeInTheDocument();
    });

    it('renders tenant domains and a fallback when unset', () => {
        render(<DashboardIndex {...defaultProps} />);
        expect(screen.getByText('acme.upepofinance.com')).toBeInTheDocument();
        expect(screen.getByText('No domain yet')).toBeInTheDocument();
    });

    it('renders no trend badges when trends are null', () => {
        render(
            <DashboardIndex
                {...defaultProps}
                stats={{
                    ...stats,
                    tenants_trend: null,
                    mrr_trend: null,
                    mrr_yoy: null,
                    subs_trend: null,
                }}
            />,
        );
        expect(screen.queryByText(/YoY/)).not.toBeInTheDocument();
    });
});
