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

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

const mockPost = vi.fn();
const mockPut = vi.fn();
const mockSetData = 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: vi.fn(() => ({
        props: {
            auth: { adminRole: 'super_admin', adminPermissions: [] },
            flash: {},
            errors: {},
        },
    })),
    useForm: vi.fn((defaults: any) => ({
        data: { ...defaults },
        setData: mockSetData,
        post: mockPost,
        put: mockPut,
        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/PageHeader', () => ({
    default: ({ title }: any) => <h2>{title}</h2>,
}));

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

const EXISTING_ANNOUNCEMENT = {
    id: 'dd000001-0000-0000-0000-000000000001',
    title: 'Existing Feature Update',
    body: 'This is the full body of the announcement.',
    published_at: '2025-06-01T10:00',
    tags: 'feature, update',
    status: 'published',
    created_at: '2025-05-28T00:00:00Z',
};

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

describe('Admin/Announcements/Form — create mode', () => {
    it('renders inside AdminLayout without crashing', () => {
        render(<AnnouncementForm />);
        expect(screen.getByTestId('admin-layout')).toBeInTheDocument();
    });

    it('sets AdminLayout title to "New Announcement" in create mode', () => {
        render(<AnnouncementForm />);
        expect(screen.getByTestId('admin-layout')).toHaveAttribute(
            'data-title',
            'New Announcement',
        );
    });

    it('shows "New Announcement" heading in create mode', () => {
        render(<AnnouncementForm />);
        expect(
            screen.getByRole('heading', { name: 'New Announcement' }),
        ).toBeInTheDocument();
    });

    it('renders a blank title input in create mode', () => {
        render(<AnnouncementForm />);
        const titleInput = screen.getByPlaceholderText("What's new?");
        expect(titleInput).toBeInTheDocument();
        expect(titleInput).toHaveValue('');
    });

    it('renders a blank body textarea in create mode', () => {
        render(<AnnouncementForm />);
        expect(
            screen.getByPlaceholderText(/describe the feature update/i),
        ).toHaveValue('');
    });

    it('renders a tags input with comma-separated hint', () => {
        render(<AnnouncementForm />);
        expect(
            screen.getByPlaceholderText(/comma-separated/i),
        ).toBeInTheDocument();
        expect(
            screen.getByText(/Separate multiple tags with commas/i),
        ).toBeInTheDocument();
    });

    it('renders a publish date input with helper text', () => {
        render(<AnnouncementForm />);
        expect(
            screen.getByText(/Leave blank to save as draft/i),
        ).toBeInTheDocument();
    });

    it('renders a "Save draft" submit button when no publish date is set', () => {
        render(<AnnouncementForm />);
        expect(
            screen.getByRole('button', { name: /save draft/i }),
        ).toBeInTheDocument();
    });

    it('renders a Cancel link back to /admin/announcements', () => {
        render(<AnnouncementForm />);
        expect(screen.getByRole('link', { name: /cancel/i })).toHaveAttribute(
            'href',
            '/admin/announcements',
        );
    });
});

describe('Admin/Announcements/Form — edit mode', () => {
    it('sets AdminLayout title to "Edit Announcement" in edit mode', () => {
        render(<AnnouncementForm announcement={EXISTING_ANNOUNCEMENT} />);
        expect(screen.getByTestId('admin-layout')).toHaveAttribute(
            'data-title',
            'Edit Announcement',
        );
    });

    it('shows "Edit Announcement" heading in edit mode', () => {
        render(<AnnouncementForm announcement={EXISTING_ANNOUNCEMENT} />);
        expect(
            screen.getByRole('heading', { name: 'Edit Announcement' }),
        ).toBeInTheDocument();
    });

    it('pre-fills the title input with the existing title', () => {
        render(<AnnouncementForm announcement={EXISTING_ANNOUNCEMENT} />);
        expect(screen.getByPlaceholderText("What's new?")).toHaveValue(
            'Existing Feature Update',
        );
    });

    it('pre-fills the body textarea with existing body', () => {
        render(<AnnouncementForm announcement={EXISTING_ANNOUNCEMENT} />);
        expect(
            screen.getByPlaceholderText(/describe the feature update/i),
        ).toHaveValue('This is the full body of the announcement.');
    });

    it('pre-fills the tags input with existing tags', () => {
        render(<AnnouncementForm announcement={EXISTING_ANNOUNCEMENT} />);
        expect(screen.getByPlaceholderText(/comma-separated/i)).toHaveValue(
            'feature, update',
        );
    });

    it('shows "Update" submit button in edit mode when publish date is set', () => {
        render(<AnnouncementForm announcement={EXISTING_ANNOUNCEMENT} />);
        expect(
            screen.getByRole('button', { name: /update/i }),
        ).toBeInTheDocument();
    });
});
