import React from 'react';
import {
    AppShell,
    Navbar,
    Header,
    Group,
    Text,
    MediaQuery,
    Burger,
    useMantineTheme,
    Box,
    Container,
    Menu,
    Avatar,
    Button,
    Stack,
    ActionIcon,
    Indicator,
    Loader,
    Anchor,
    Badge,
    Modal,
    Tooltip,
} from '@mantine/core';

import Sidebar from '../components/sidebar';
import ThemeToggle from '../components/theme-toggle';
import { SidebarProvider } from '@/components/ui/sidebar';
import { usePage, Link, router } from '@inertiajs/react';
import { Alert } from '@mantine/core';
import { notifications } from "@mantine/notifications";
import { useEffect } from "react";
import { IconInfoCircle, IconCircleX, IconAlertCircle, IconSettings, IconLogout, IconBell, IconFileDollar, IconUserPlus } from "@tabler/icons-react";
import { logout } from '@/routes';
import { edit } from '@/routes/profile';
import { SharedData } from '@/types';
import { MantineReactTable, type MRT_ColumnDef, type MRT_Row } from 'mantine-react-table';

type PendingInvoiceNotification = {
    id: number;
    client_id: number | null;
    invoice_no: string;
    pending_sql_acc_code?: string | null;
    pending_client_name?: string | null;
    requires_client?: boolean;
    payment_no: string | null;
    management_fee: string | number | null;
    media_fee: string | number | null;
    created_at: string | null;
    previous_payments?: PreviousPaymentRecord[];
    invoice_billing_totals?: {
        media_fee: string | number | null;
        management_fee: string | number | null;
    };
    client?: {
        name: string | null;
    } | null;
};

type PreviousPaymentRecord = {
    payment_number: string | null;
    status: string | null;
    sql_created_at: string | null;
    amount: string | number | null;
    media_fee: string | number | null;
    management_fee: string | number | null;
    invoice_media_fee: string | number | null;
    invoice_management_fee: string | number | null;
    invoice_number: string | null;
};

type AppNotification = {
    type: 'pending_invoice' | string;
    title: string;
    description: string;
    count: number;
};

function AppNotifications() {
    const [notifications, setNotifications] = React.useState<AppNotification[]>([]);
    const [invoices, setInvoices] = React.useState<PendingInvoiceNotification[]>([]);
    const [count, setCount] = React.useState(0);
    const [isLoadingNotifications, setIsLoadingNotifications] = React.useState(true);
    const [isLoadingInvoices, setIsLoadingInvoices] = React.useState(false);
    const [pendingInvoicesOpened, setPendingInvoicesOpened] = React.useState(false);

    const dateFormatter = React.useMemo(
        () =>
            new Intl.DateTimeFormat('en-MY', {
                day: '2-digit',
                month: 'short',
                year: 'numeric',
            }),
        [],
    );

    const formatAmount = (amount: string | number | null) => {
        const value = Number(amount ?? 0);

        return new Intl.NumberFormat('en-US', {
            minimumFractionDigits: 2,
            maximumFractionDigits: 2,
        }).format(Number.isFinite(value) ? value : 0);
    };

    const formatDate = (date: string | null) => {
        if (!date) {
            return '-';
        }

        const value = new Date(date);

        return Number.isNaN(value.getTime()) ? '-' : dateFormatter.format(value);
    };

    const pendingInvoiceColumns = React.useMemo<MRT_ColumnDef<PendingInvoiceNotification>[]>(
        () => [
            {
                accessorKey: 'invoice_no',
                header: 'Invoice',
                Cell: ({ row }) => (
                    <Stack spacing={1}>
                        <Anchor
                            component={Link}
                            href={
                                row.original.requires_client
                                    ? `/client-invoices/${row.original.id}/client/create`
                                    : `/client-invoices/${row.original.id}/edit`
                            }
                            size="sm"
                            weight={700}
                        >
                            {row.original.invoice_no}
                        </Anchor>
                        <Text size="xs" color="dimmed">
                            {row.original.requires_client ? 'Client setup required' : 'Ready for review'}
                        </Text>
                    </Stack>
                ),
            },
            {
                id: 'client',
                header: 'Client',
                accessorFn: (invoice) => invoice.client?.name ?? invoice.pending_client_name ?? '-',
                Cell: ({ cell }) => (
                    <Text size="sm" lineClamp={1}>
                        {cell.getValue<string>()}
                    </Text>
                ),
            },
            {
                id: 'sql_acc_code',
                header: 'SQL Acc Code',
                accessorFn: (invoice) => invoice.pending_sql_acc_code ?? '-',
                Cell: ({ cell }) => <Text size="sm">{cell.getValue<string>()}</Text>,
            },
            {
                id: 'invoice_management_fee',
                header: 'Invoice Management Fee',
                accessorFn: (invoice) => invoice.invoice_billing_totals?.management_fee ?? 0,
                Cell: ({ row }) => (
                    <Text size="sm" weight={600} align="right">
                        {formatAmount(row.original.invoice_billing_totals?.management_fee ?? 0)}
                    </Text>
                ),
            },
            {
                id: 'invoice_media_fee',
                header: 'Invoice Media Fee',
                accessorFn: (invoice) => invoice.invoice_billing_totals?.media_fee ?? 0,
                Cell: ({ row }) => (
                    <Text size="sm" weight={600} align="right">
                        {formatAmount(row.original.invoice_billing_totals?.media_fee ?? 0)}
                    </Text>
                ),
            },
            {
                accessorKey: 'management_fee',
                header: 'Payment Management Fee',
                Cell: ({ row }) => (
                    <Text size="sm" weight={600} align="right">
                        {formatAmount(row.original.management_fee)}
                    </Text>
                ),
            },
            {
                accessorKey: 'media_fee',
                header: 'Payment Media Fee',
                Cell: ({ row }) => (
                    <Text size="sm" weight={600} align="right">
                        {formatAmount(row.original.media_fee)}
                    </Text>
                ),
            },
            {
                id: 'payment_date',
                header: 'Payment Date',
                accessorFn: (invoice) => invoice.created_at,
                Cell: ({ row }) => (
                    <Text size="sm">
                        {formatDate(row.original.created_at)}
                    </Text>
                ),
            },
            {
                accessorKey: 'created_at',
                header: 'Created',
                Cell: ({ row }) => (
                    <Text size="sm">
                        {formatDate(row.original.created_at)}
                    </Text>
                ),
            },
        ],
        [],
    );

    const renderPreviousPaymentsPanel = ({ row }: { row: MRT_Row<PendingInvoiceNotification> }) => {
        const records = row.original.previous_payments ?? [];

        if (records.length === 0) {
            return (
                <Box px="md" py="sm">
                    <Text size="sm" color="dimmed">
                        No previous payment records found for this invoice.
                    </Text>
                </Box>
            );
        }

        return (
            <Box px="md" py="sm">
                <Stack spacing="xs">
                    <Group position="apart">
                        <Text size="sm" weight={700}>
                            Previous Payment Records
                        </Text>
                        <Badge variant="light">{records.length}</Badge>
                    </Group>
                    <Box sx={{ overflowX: 'auto' }}>
                        <table style={{ width: '100%', borderCollapse: 'collapse' }}>
                            <thead>
                                <tr>
                                    <th style={{ textAlign: 'left', padding: '8px' }}>Payment No</th>
                                    <th style={{ textAlign: 'left', padding: '8px' }}>Status</th>
                                    <th style={{ textAlign: 'left', padding: '8px' }}>Payment Date</th>
                                    <th style={{ textAlign: 'right', padding: '8px' }}>Media Fee</th>
                                    <th style={{ textAlign: 'right', padding: '8px' }}>Management Fee</th>
                                    <th style={{ textAlign: 'right', padding: '8px' }}>Invoice Media</th>
                                    <th style={{ textAlign: 'right', padding: '8px' }}>Invoice Management</th>
                                    <th style={{ textAlign: 'right', padding: '8px' }}>Total</th>
                                </tr>
                            </thead>
                            <tbody>
                                {records.map((record, index) => (
                                    <tr key={`${record.payment_number ?? 'payment'}-${index}`}>
                                        <td style={{ padding: '8px' }}>{record.payment_number ?? '-'}</td>
                                        <td style={{ padding: '8px' }}>
                                            <Badge color={record.status === 'Processed' ? 'green' : 'gray'} variant="light">
                                                {record.status ?? '-'}
                                            </Badge>
                                        </td>
                                        <td style={{ padding: '8px' }}>{formatDate(record.sql_created_at)}</td>
                                        <td style={{ padding: '8px', textAlign: 'right' }}>
                                            {formatAmount(record.media_fee)}
                                        </td>
                                        <td style={{ padding: '8px', textAlign: 'right' }}>
                                            {formatAmount(record.management_fee)}
                                        </td>
                                        <td style={{ padding: '8px', textAlign: 'right' }}>
                                            {formatAmount(record.invoice_media_fee)}
                                        </td>
                                        <td style={{ padding: '8px', textAlign: 'right' }}>
                                            {formatAmount(record.invoice_management_fee)}
                                        </td>
                                        <td style={{ padding: '8px', textAlign: 'right', fontWeight: 700 }}>
                                            {formatAmount(record.amount)}
                                        </td>
                                    </tr>
                                ))}
                            </tbody>
                        </table>
                    </Box>
                </Stack>
            </Box>
        );
    };

    const renderPendingInvoiceActions = ({ row }: { row: MRT_Row<PendingInvoiceNotification> }) => (
        <Group spacing="xs" noWrap>
            {row.original.requires_client ? (
                <ActionIcon
                    component={Link}
                    href={`/client-invoices/${row.original.id}/client/create`}
                    color="blue"
                    variant="light"
                >
                    <Tooltip label="Link client" withArrow withinPortal>
                        <IconUserPlus size={18} />
                    </Tooltip>
                </ActionIcon>
            ) : null}
            <ActionIcon
                component="a"
                href={`/client-invoices/pdf/invoice/${row.original.id}`}
                target="_blank"
            >
                <Tooltip label="View Invoice" withArrow withinPortal>
                    <IconFileDollar color="green" />
                </Tooltip>
            </ActionIcon>
        </Group>
    );

    useEffect(() => {
        let isMounted = true;

        const loadNotifications = async () => {
            try {
                const response = await fetch('/api/notifications', {
                    headers: {
                        Accept: 'application/json',
                    },
                    credentials: 'same-origin',
                });

                if (!response.ok) {
                    throw new Error('Unable to load pending invoices.');
                }

                const data = await response.json();

                if (isMounted) {
                    setNotifications(data.notifications ?? []);
                    setCount(data.count ?? 0);
                }
            } catch {
                if (isMounted) {
                    setNotifications([]);
                    setCount(0);
                }
            } finally {
                if (isMounted) {
                    setIsLoadingNotifications(false);
                }
            }
        };

        loadNotifications();

        return () => {
            isMounted = false;
        };
    }, []);

    const loadPendingInvoices = React.useCallback(async () => {
        setIsLoadingInvoices(true);

        try {
            const response = await fetch('/api/customer-invoices/pending', {
                headers: {
                    Accept: 'application/json',
                },
                credentials: 'same-origin',
            });

            if (!response.ok) {
                throw new Error('Unable to load pending invoices.');
            }

            const data = await response.json();

            setInvoices(data.invoices ?? []);
            console.log(data.invoices);
        } catch {
            setInvoices([]);
        } finally {
            setIsLoadingInvoices(false);
        }
    }, []);

    const openNotification = (notification: AppNotification) => {
        if (notification.type === 'pending_invoice') {
            setPendingInvoicesOpened(true);
            loadPendingInvoices();
        }
    };

    return (
        <>
            <Menu shadow="xl" width={360} position="bottom-end" withinPortal>
                <Menu.Target>
                    <Indicator
                        label={count > 99 ? '99+' : count}
                        size={18}
                        disabled={count === 0}
                        color="red"
                    >
                        <ActionIcon
                            variant="light"
                            color="blue"
                            size="lg"
                            radius="xl"
                            aria-label="Notifications"
                        >
                            <IconBell size={20} />
                        </ActionIcon>
                    </Indicator>
                </Menu.Target>
                <Menu.Dropdown p={0}>
                    <Box
                        px="md"
                        py="sm"
                        sx={(theme) => ({
                            borderBottom: `1px solid ${theme.colorScheme === 'dark'
                                ? theme.colors.dark[4]
                                : theme.colors.gray[2]
                                }`,
                            backgroundColor:
                                theme.colorScheme === 'dark'
                                    ? theme.colors.dark[6]
                                    : theme.colors.gray[0],
                        })}
                    >
                        <Group position="apart" align="center">
                            <Stack spacing={2}>
                                <Text size="sm" weight={700}>
                                    Notifications
                                </Text>
                                <Text size="xs" color="dimmed">
                                    Updates grouped by notification type
                                </Text>
                            </Stack>
                            <Badge color={count > 0 ? 'red' : 'gray'} variant="filled">
                                {count} pending
                            </Badge>
                        </Group>
                    </Box>
                    {isLoadingNotifications ? (
                        <Group position="center" py="xl">
                            <Stack spacing="xs" align="center">
                                <Loader size="sm" />
                                <Text color="dimmed" size="sm">
                                    Loading notifications...
                                </Text>
                            </Stack>
                        </Group>
                    ) : notifications.length === 0 ? (
                        <Stack spacing={4} align="center" py="xl">
                            <Text weight={600} size="sm">
                                All caught up
                            </Text>
                            <Text color="dimmed" size="sm">
                                No notifications need your attention.
                            </Text>
                        </Stack>
                    ) : (
                        <Stack spacing={0}>
                            {notifications.map((notification) => (
                                <Menu.Item
                                    key={notification.type}
                                    onClick={() => openNotification(notification)}
                                    icon={<IconAlertCircle size={18} />}
                                    rightSection={
                                        <Badge color="red" variant="light">
                                            {notification.count}
                                        </Badge>
                                    }
                                >
                                    <Stack spacing={2}>
                                        <Text size="sm" weight={700}>
                                            {notification.title}
                                        </Text>
                                        <Text size="xs" color="dimmed">
                                            {notification.description}
                                        </Text>
                                    </Stack>
                                </Menu.Item>
                            ))}
                        </Stack>
                    )}
                </Menu.Dropdown>
            </Menu>

            <Modal
                opened={pendingInvoicesOpened}
                onClose={() => setPendingInvoicesOpened(false)}
                title="Pending invoice approvals"
                size="xxl"
            >
                {isLoadingInvoices ? (
                    <Group position="center" py="xl">
                        <Stack spacing="xs" align="center">
                            <Loader size="sm" />
                            <Text color="dimmed" size="sm">
                                Loading pending invoices...
                            </Text>
                        </Stack>
                    </Group>
                ) : invoices.length === 0 ? (
                    <Stack spacing={4} align="center" py="xl">
                        <Text weight={600} size="sm">
                            All caught up
                        </Text>
                        <Text color="dimmed" size="sm">
                            No invoices are waiting for approval.
                        </Text>
                    </Stack>
                ) : (
                    <MantineReactTable
                        columns={pendingInvoiceColumns}
                        data={invoices}
                        renderRowActions={renderPendingInvoiceActions}
                        renderDetailPanel={renderPreviousPaymentsPanel}
                        enableExpanding
                        getRowCanExpand={() => true}
                        positionExpandColumn="first"
                        enableRowActions
                        positionActionsColumn="last"
                        enablePagination={false}
                        enableGlobalFilter={false}
                        enableColumnFilters={false}
                        enableTopToolbar={false}
                        enableBottomToolbar={false}
                        initialState={{ density: 'xs' }}
                    />
                )}
            </Modal>
        </>
    );
}
type Props = {
    children: React.ReactNode;
    breadcrumbs?: unknown;
};

export default function AppLayout({ children }: Props) {
    const theme = useMantineTheme();
    const [opened, setOpened] = React.useState(false);

    const isDark = theme.colorScheme === 'dark';

    const page = usePage<SharedData>();
    const { flash, auth } = page.props as any;
    useEffect(() => {

        if (flash['message-info']) {
            notifications.show({
                title: 'Info',
                color: 'blue',
                icon: <IconInfoCircle />,
                message: flash['message-info'],
            });
        }

        if (flash['message-warning']) {
            notifications.show({
                title: 'Warning',
                color: 'yellow',
                icon: <IconAlertCircle />,
                message: flash['message-warning'],
            });
        }

        if (flash['message-error']) {
            notifications.show({
                title: 'Error',
                color: 'red',
                icon: <IconCircleX />,
                message: flash['message-error'],
            });
        }

    }, [flash]);
    return (
        <SidebarProvider open={opened} onOpenChange={setOpened}>
            <AppShell
                padding="lg"
                navbarOffsetBreakpoint="sm"
                navbar={
                    <Navbar
                        width={{ base: 260 }}
                        hiddenBreakpoint="sm"
                        hidden={!opened}
                        p="md"
                        style={{
                            borderRight: `1px solid ${isDark ? theme.colors.dark[4] : theme.colors.gray[3]
                                }`,
                        }}
                    >
                        <Sidebar />
                    </Navbar>
                }
                header={
                    <Header
                        height={60}
                        px="lg"
                        style={{
                            backgroundColor: isDark ? theme.colors.dark[6] : theme.white,
                            borderBottom: `1px solid ${isDark ? theme.colors.dark[4] : theme.colors.gray[3]
                                }`,
                        }}
                    >
                        <Group position="apart" align="center" style={{ height: '100%' }}>
                            <Group spacing="sm">
                                <MediaQuery largerThan="sm" styles={{ display: 'none' }}>
                                    <Burger
                                        opened={opened}
                                        onClick={() => setOpened((o) => !o)}
                                        size="sm"
                                    />
                                </MediaQuery>

                                <Text weight={700} size="lg">
                                    Inspiren SEM Tool
                                </Text>
                            </Group>

                            <Group spacing="sm">
                                <AppNotifications />
                                <ThemeToggle />
                                <Menu shadow="md" width={220}>
                                    <Menu.Target>
                                        <Button variant="subtle">
                                            <Avatar color="gray" radius="xl" size="sm">
                                                {auth.user.name
                                                    .split(' ')
                                                    .map((part: string) => part[0])
                                                    .join('')
                                                    .toUpperCase()}
                                            </Avatar>
                                        </Button>
                                    </Menu.Target>
                                    <Menu.Dropdown>
                                        <Menu.Label>
                                            <Stack spacing={0}>
                                                <Text size="sm">{auth.user.name}</Text>
                                                <Text size="xs" color="dimmed">
                                                    {auth.user.email}
                                                </Text>
                                            </Stack>
                                        </Menu.Label>
                                        <Menu.Item
                                            icon={<IconSettings size={16} />}
                                            component={Link}
                                            href={edit()}
                                            as="button"
                                            prefetch
                                        >
                                            Settings
                                        </Menu.Item>
                                        <Menu.Item
                                            icon={<IconLogout size={16} />}
                                            onClick={() =>
                                                router.post(logout(), {
                                                    preserveState: true,
                                                })
                                            }
                                        >
                                            Log out
                                        </Menu.Item>
                                    </Menu.Dropdown>
                                </Menu>
                            </Group>
                        </Group>
                    </Header>
                }
                styles={{
                    main: {
                        backgroundColor: isDark
                            ? theme.colors.dark[7]
                            : theme.colors.gray[0],
                        minHeight: '100vh',
                        maxWidth: '100vw',
                        overflowX: 'hidden',
                    },
                }}
            >
                <Container fluid px={{ base: 'xs', sm: 'md', lg: 'lg' }} style={{ maxWidth: '100%', overflowX: 'hidden' }}>
                    <Box
                        style={{
                            backgroundColor: isDark ? theme.colors.dark[6] : theme.white,
                            borderRadius: theme.radius.md,
                            padding: theme.spacing.lg,
                            boxShadow: theme.shadows.sm,
                            maxWidth: '100%',
                            minWidth: 0,
                            overflowX: 'auto',
                        }}
                    >
                        {children}
                    </Box>
                </Container>
            </AppShell>
        </SidebarProvider>
    );
}
