import {
  ActionIcon,
  Badge,
  Button,
  Center,
  Code,
  Flex,
  Group,
  Loader,
  Menu,
  ScrollArea,
  Text,
  useMantineTheme,
} from '@mantine/core';
import { useMediaQuery } from '@mantine/hooks';
import { modals } from '@mantine/modals';
import { notifications } from '@mantine/notifications';
import {
  IconFileTypeCsv,
  IconFileTypeSql,
  IconRefresh,
  IconSelect,
  IconTools,
  IconTrash,
} from '@tabler/icons-react';
import { __, sprintf } from '@wordpress/i18n';
import { DataTable } from 'mantine-datatable';
import { useEffect, useState } from 'react';
import useSWR from 'swr';
import { exportWithFormat, post } from '../utils';
import { BannersMultiSelect } from './BannersMultiSelect';
import { BulkActions } from './BulkActions';
import { CampaignsMultiSelect } from './CampaignsMultiSelect';

const PAGE_SIZES = [15, 20, 30];

export default function AnalyticsDataTable({ analytic = 'clicks' }) {
  const isTouch = useMediaQuery('(pointer: coarse)');
  const theme = useMantineTheme();
  const isManageAnalytics = !!window.WPBannerize.manage_analytics;

  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(PAGE_SIZES[1]);
  const [selectedRecords, setSelectedRecords] = useState([]);
  const [sortStatus, setSortStatus] = useState({
    columnAccessor: 'date',
    direction: 'desc',
  });
  const [campaigns, setCampaigns] = useState([]);
  const [banners, setBanners] = useState([]);

  const label =
    analytic === 'clicks'
      ? __('Clicks', 'wp-bannerize')
      : __('Impressions', 'wp-bannerize');

  const action = `wp_bannerize_get_${analytic}`;
  const key = `wp_bannerize_get_${analytic}${sortStatus.columnAccessor}${
    sortStatus.direction
  }${pageSize}${page}${campaigns.join(',')}${banners.join(',')}`;
  const orderBy = `${sortStatus.columnAccessor} ${sortStatus.direction}`;

  const fetcher = async () =>
    post(action, {
      page,
      orderBy,
      pageSize,
      page,
      campaigns,
      banners,
    });

  const { data, error, isLoading, isValidating, mutate } = useSWR(key, fetcher);

  useEffect(() => {
    setPage(1);
  }, [pageSize]);

  const handleDelete = async record => {
    const code = sprintf(
      __('Date: %s\nBanner ID: %s\nTitle: %s\nCampaigns: %s', 'wp-bannerize'),
      record.date,
      record.banner_id,
      record.title,
      record.campaigns,
    );

    modals.openConfirmModal({
      title: __('Please confirm your action', 'wp-bannerize'),
      centered: true,
      children: (
        <Text size="sm">
          {__('Are your sure you want to delete the record', 'wp-bannerize')}
          <Code block>{code}</Code>
          {__('This action cannot be undone', 'wp-bannerize')}
        </Text>
      ),
      labels: {
        confirm: __('Confirm', 'wp-bannerize'),
        cancel: __('Cancel', 'wp-bannerize'),
      },
      confirmProps: { color: 'red' },
      onConfirm: async () => {
        await post(`wp_bannerize_delete_${analytic}`, {
          id: record.id,
        });

        mutate();

        notifications.show({
          withBorder: true,
          color: 'orange',
          title: `${label} ${__('Deleted', 'wp-bannerize')}`,
          message: `${label} ${__('has been deleted', 'wp-bannerize')}.`,
        });
      },
    });
  };

  const handleBulkActions = async (action, analytic) => {
    if (action === 'Delete') {
      const code = selectedRecords
        .map(record => {
          return `Date: ${record.date}\nBanner ID: ${record.banner_id}\nTitle: ${record.title}\nCampaigns: ${record.campaigns}`;
        })
        .join('\n\n');

      modals.openConfirmModal({
        title: __('Please confirm your action', 'wp-bannerize'),
        centered: true,
        children: (
          <Text size="sm">
            {__(
              'Are your sure you want to delete the selected records',
              'wp-bannerize',
            )}
            <ScrollArea h={250}>
              <Code block>{code}</Code>
            </ScrollArea>
            {__('This action cannot be undone', 'wp-bannerize')}
          </Text>
        ),
        labels: {
          confirm: __('Confirm', 'wp-bannerize'),
          cancel: __('Cancel', 'wp-bannerize'),
        },
        confirmProps: { color: 'red' },
        onConfirm: async () => {
          await post(`wp_bannerize_delete_${analytic}`, {
            id: selectedRecords.map(record => record.id),
          });

          setSelectedRecords([]);
          mutate();

          notifications.show({
            withBorder: true,
            color: 'orange',
            title: `${label} ${__('Deleted', 'wp-bannerize')}`,
            message: `${label} ${__('have been deleted', 'wp-bannerize')}.`,
          });
        },
      });
    }
  };

  if (isLoading || !data) {
    return (
      <Center>
        <Loader />
      </Center>
    );
  }

  return (
    <>
      <Group mt={8} grow>
        {isManageAnalytics && (
          <BulkActions
            analytic={analytic}
            selectedRecords={selectedRecords}
            onBulkAction={handleBulkActions}
          />
        )}
        <Group>
          <Menu shadow="md" withArrow>
            <Menu.Target>
              <Button
                size="xs"
                rightSection={<IconSelect style={{ width: 14 }} />}>
                {__('Export', 'wp-bannerize')}
              </Button>
            </Menu.Target>
            <Menu.Dropdown>
              <Menu.Item
                onClick={async () => {
                  exportWithFormat('csv', analytic);
                }}
                leftSection={
                  <IconFileTypeCsv width={18} color={theme.colors.blue[6]} />
                }>
                {__('Export CSV', 'wp-bannerize')}
              </Menu.Item>
              <Menu.Item
                onClick={async () => {
                  exportWithFormat('sql', analytic);
                }}
                leftSection={
                  <IconFileTypeSql width={18} color={theme.colors.blue[6]} />
                }>
                {__('Export SQL', 'wp-bannerize')}
              </Menu.Item>
            </Menu.Dropdown>
          </Menu>
        </Group>
        <CampaignsMultiSelect campaigns={campaigns} onChange={setCampaigns} />
        <BannersMultiSelect banners={banners} onChange={setBanners} />
      </Group>
      <DataTable
        mt={16}
        striped
        pinLastColumn
        scrollAreaProps={{ type: 'scroll' }}
        height={'calc(100vh - 264px)'}
        fetching={isLoading || isValidating}
        borderRadius="md"
        withTableBorder
        withColumnBorders
        highlightOnHover
        records={data.items}
        selectedRecords={isManageAnalytics ? selectedRecords : null}
        //textSelectionDisabled={true}
        onSelectedRecordsChange={setSelectedRecords}
        totalRecords={+data.total}
        recordsPerPage={pageSize}
        page={page}
        onPageChange={p => setPage(p)}
        recordsPerPageOptions={PAGE_SIZES}
        onRecordsPerPageChange={setPageSize}
        sortStatus={sortStatus}
        onSortStatusChange={setSortStatus}
        columns={[
          { accessor: 'date', sortable: true, noWrap: true },
          { accessor: 'banner_id', sortable: true },
          { accessor: 'title', noWrap: true },
          {
            accessor: 'campaigns',
            render: record => {
              if (!record.campaigns) return null;
              return (
                <Group gap={2}>
                  {record.campaigns.split(',').map((campaign, index) => (
                    <Badge
                      color={`violet.${(index + 3) % 9}`}
                      size="xs"
                      key={campaign}>
                      {campaign}
                    </Badge>
                  ))}
                </Group>
              );
            },
          },
          {
            accessor: 'referrer',
            sortable: true,
            ellipsis: true,
            width: 'auto',
            render: record => (
              <Text maw={400} size="sm" c="dimmed" truncate>
                {record.referrer}
              </Text>
            ),
          },
          {
            accessor: 'ip',
            sortable: true,
          },
          {
            accessor: 'actions',
            width: 50,
            textAlign: 'center',
            title: (
              <IconTools style={{ width: 16, color: theme.colors.blue[5] }} />
            ),
            render: record => (
              <Flex>
                <ActionIcon
                  mx="auto"
                  disabled={!isManageAnalytics}
                  title={
                    isManageAnalytics
                      ? `${__('Delete', 'wp-bannerize')} ${label}`
                      : __(
                          'You do not have permission to delete records',
                          'wp-bannerize',
                        )
                  }
                  variant="subtle"
                  color="red"
                  onClick={e => {
                    e.stopPropagation();
                    handleDelete(record);
                  }}>
                  <IconTrash size={18} />
                </ActionIcon>
              </Flex>
            ),
            footer: (
              <Group justify="center">
                <ActionIcon
                  variant="transparent"
                  title="Refresh"
                  onClick={async () => {
                    await mutate();
                  }}>
                  <IconRefresh />
                </ActionIcon>
              </Group>
            ),
          },
        ]}
      />
    </>
  );
}
