'use client';

import { useState, useCallback, useEffect, useMemo } from 'react';
// @mui
import { useTheme, alpha } from '@mui/material/styles';
import Tab from '@mui/material/Tab';
import Tabs from '@mui/material/Tabs';
import Card from '@mui/material/Card';
import Table from '@mui/material/Table';
import Stack from '@mui/material/Stack';
import Button from '@mui/material/Button';
import Divider from '@mui/material/Divider';
import Container from '@mui/material/Container';
import TableBody from '@mui/material/TableBody';
import TableContainer from '@mui/material/TableContainer';
// routes
import { paths } from 'src/routes/paths';
import { useRouter } from 'src/routes/hooks';
import { RouterLink } from 'src/routes/components';
// utils
import { fTimestamp } from 'src/utils/format-time';
// components
import Label from 'src/components/label';
import Iconify from 'src/components/iconify';
import Scrollbar from 'src/components/scrollbar';
import { useSettingsContext } from 'src/components/settings';
import CustomBreadcrumbs from 'src/components/custom-breadcrumbs';
import {
  useTable,
  getComparator,
  emptyRows,
  TableNoData,
  TableEmptyRows,
  TableHeadCustom,
  TablePaginationCustom,
} from 'src/components/table';
// types
import { Invoice, InvoiceStatus, InvoiceTableFilters, InvoiceTableFilterValue } from 'src/schemas';
//
import deleteFromFirebaseStorage from 'src/utils/delete-from-firebase-storage';
// fetch
import { useDeleteInvoice, useGetInvoices } from 'src/api/invoice';
import { collections, removeDocument } from 'src/lib/firestore';
import { mutate } from 'swr';
import { useBoolean } from 'src/hooks/use-boolean';
import InvoiceAnalytic from '../invoice-analytic';
import InvoiceTableRow from '../invoice-table-row';
import InvoiceTableFiltersResult from '../invoice-table-filters-result';
import InvoiceTableToolbar from '../invoice-table-toolbar';
import MailCompose from '../mail-compose';

// ----------------------------------------------------------------------

const TABLE_HEAD = [
  { id: 'invoiceNumber', label: 'Customer' },
  { id: 'price', label: 'Amount' },
  { id: 'currency', label: 'Currency' },
  { id: 'invoicePeriod', label: 'Invoice Period' },
  { id: 'createDate', label: 'Create' },
  { id: 'dueDate', label: 'Due' },
  { id: 'sent', label: 'Sent', align: 'center' },
  { id: 'status', label: 'Status' },
  { id: '' },
];

const defaultFilters: InvoiceTableFilters = {
  name: '',
  service: [],
  status: 'all',
  startDate: new Date('2024-01-01T00:00:00Z'),
  endDate: null,
};

// ----------------------------------------------------------------------

interface StatusTotals {
  EUR: number;
  USD: number;
}

type ResultsType = {
  [key in 'total' | InvoiceStatus]: StatusTotals;
};

const getEURtoUSDExchangeRate = async () => {
  try {
    // const response = await fetch(
    //   'http://api.exchangeratesapi.io/v1/latest?access_key=248cc5d9f103fcb183ed4987f2d85b3b&base=EUR&symbols=USD'
    // );
    // const data = await response.json();
    // return data.rates.USD;
    return 1.05;
  } catch (error) {
    console.error('Error fetching the exchange rate:', error);
    return null;
  }
};

const getTotalAmountForAllStatuses = async (invoices: Invoice[]) => {
  const eurToUsdRate = await getEURtoUSDExchangeRate();
  if (!eurToUsdRate) {
    throw new Error("Couldn't fetch the exchange rate.");
  }

  const results: ResultsType = {
    total: { EUR: 0, USD: 0 },
    // excluded
    processing: { EUR: 0, USD: 0 },
    paid: { EUR: 0, USD: 0 },
    pending: { EUR: 0, USD: 0 },
    overdue: { EUR: 0, USD: 0 },
    draft: { EUR: 0, USD: 0 },
  };

  invoices.forEach((invoice) => {
    const updateAmounts = (key: 'total' | InvoiceStatus) => {
      const excludeProcessing = key === 'processing' ? 'pending' : key;
      if (invoice.currency === 'USD') {
        results[excludeProcessing].USD += invoice.totalAmount;
        results[excludeProcessing].EUR += invoice.totalAmount / eurToUsdRate; // Convert USD to EUR
      } else if (invoice.currency === 'EUR') {
        results[excludeProcessing].EUR += invoice.totalAmount;
        results[excludeProcessing].USD += invoice.totalAmount * eurToUsdRate; // Convert EUR to USD
      }
    };

    updateAmounts('total');
    updateAmounts(invoice.status as InvoiceStatus);
  });

  return results;
};

export default function InvoiceListView() {
  const theme = useTheme();

  const settings = useSettingsContext();

  const [analytics, setAnalytics] = useState({
    total: { EUR: 0, USD: 0 },
    paid: { EUR: 0, USD: 0 },
    pending: { EUR: 0, USD: 0 },
    overdue: { EUR: 0, USD: 0 },
    draft: { EUR: 0, USD: 0 },
  });

  const [sendingInvoice, setSendingInvoice] = useState<Invoice | null>(null);

  const router = useRouter();

  const table = useTable({
    defaultOrderBy: 'createDate',
    defaultOrder: 'desc',
    defaultDense: true,
    defaultRowsPerPage: 25,
  });

  const [filters, setFilters] = useState(defaultFilters);

  const { invoices: tableData } = useGetInvoices({ startDate: filters.startDate?.toISOString() });

  const invoiceMutationKey = useMemo(
    () => [
      collections.invoice,
      JSON.stringify({
        where: [['createDate', '>=', filters.startDate]],
        orderBy: 'createDate',
        direction: 'desc',
      }),
    ],
    [filters]
  );

  const dateError =
    filters.startDate && filters.endDate
      ? filters.startDate.getTime() > filters.endDate.getTime()
      : false;

  const dataFiltered = applyFilter({
    inputData: tableData,
    comparator: getComparator(table.order, table.orderBy),
    filters,
    dateError,
  });

  // const dataInPage = dataFiltered.slice(
  //   table.page * table.rowsPerPage,
  //   table.page * table.rowsPerPage + table.rowsPerPage
  // );

  const denseHeight = table.dense ? 56 : 76;

  const canReset =
    !!filters.name ||
    !!filters.service.length ||
    filters.status !== 'all' ||
    (!!filters.startDate && !!filters.endDate);

  const notFound = (!dataFiltered.length && canReset) || !dataFiltered.length;

  const getInvoiceLength = (status: string) =>
    tableData.filter((item) => item.status === status).length;

  // const getTotalAmount = (status: string) =>
  //   sumBy(
  //     tableData.filter((item) => item.status === status),
  //     'totalAmount'
  //   );

  useEffect(() => {
    if (tableData) {
      const getAnalytics = async () => {
        const analyticsStats = await getTotalAmountForAllStatuses(tableData);
        setAnalytics(analyticsStats);
      };
      getAnalytics();
    }
  }, [tableData]);

  const getPercentByStatus = (status: string) =>
    (getInvoiceLength(status) / tableData.length) * 100;

  const TABS = [
    { value: 'all', label: 'All', color: 'default', count: tableData.length },
    {
      value: 'paid',
      label: 'Paid',
      color: 'success',
      count: getInvoiceLength('paid'),
    },
    {
      value: 'pending',
      label: 'Pending',
      color: 'warning',
      count: getInvoiceLength('pending'),
    },
    {
      value: 'overdue',
      label: 'Overdue',
      color: 'error',
      count: getInvoiceLength('overdue'),
    },
    {
      value: 'draft',
      label: 'Draft',
      color: 'default',
      count: getInvoiceLength('draft'),
    },
  ] as const;

  const handleFilters = useCallback(
    (name: string, value: InvoiceTableFilterValue) => {
      table.onResetPage();
      setFilters((prevState) => ({
        ...prevState,
        [name]: value,
      }));
    },
    [table]
  );

  const { deleteInvoiceMutation } = useDeleteInvoice();

  const handleDeleteRow = useCallback(
    async (invoice: Invoice) => {
      const serializedParams = JSON.stringify({
        where: [['createDate', '>=', filters.startDate]],
        orderBy: 'createDate',
        direction: 'desc',
      });

      await deleteInvoiceMutation(invoice.id);
      await deleteFromFirebaseStorage(
        `invoices/${invoice.invoiceTo.name}/${invoice.id}-${invoice.invoiceNumber}.pdf`
      );

      mutate(invoiceMutationKey);
    },
    [filters.startDate, invoiceMutationKey]
  );

  const openCompose = useBoolean();

  const handleToggleCompose = useCallback(
    async (invoice: Invoice) => {
      setSendingInvoice(invoice);
      openCompose.onToggle();
    },
    [openCompose]
  );

  // const handleDeleteRows = useCallback(() => {
  //   const deleteRows = tableData.filter((row) => !table.selected.includes(row.id));
  //   // setTableData(deleteRows);

  //   table.onUpdatePageDeleteRows({
  //     totalRows: tableData.length,
  //     totalRowsInPage: dataInPage.length,
  //     totalRowsFiltered: dataFiltered.length,
  //   });
  // }, [dataFiltered.length, dataInPage.length, table, tableData]);

  const handleEditRow = useCallback(
    (id: string) => {
      router.push(paths.dashboard.invoice.edit(id));
    },
    [router]
  );

  const handleCopyRow = useCallback(
    (id: string) => {
      router.push(paths.dashboard.invoice.copy(id));
    },
    [router]
  );

  const handleViewRow = useCallback(
    (id: string) => {
      router.push(paths.dashboard.invoice.details(id));
    },
    [router]
  );

  const handleFilterStatus = useCallback(
    (event: React.SyntheticEvent, newValue: string) => {
      handleFilters('status', newValue);
    },
    [handleFilters]
  );

  const handleResetFilters = useCallback(() => {
    setFilters(defaultFilters);
  }, []);

  return (
    <>
      <Container maxWidth={settings.themeStretch ? false : 'lg'}>
        <CustomBreadcrumbs
          heading="List"
          links={[
            {
              name: 'Dashboard',
              href: paths.dashboard.root,
            },
            {
              name: 'Invoice',
              href: paths.dashboard.invoice.root,
            },
            {
              name: 'List',
            },
          ]}
          action={
            <Button
              component={RouterLink}
              href={paths.dashboard.invoice.new}
              variant="contained"
              startIcon={<Iconify icon="mingcute:add-line" />}
            >
              New Invoice
            </Button>
          }
          sx={{
            mb: { xs: 3, md: 5 },
          }}
        />

        <Card
          sx={{
            mb: { xs: 3, md: 5 },
          }}
        >
          <Scrollbar>
            <Stack
              direction="row"
              divider={<Divider orientation="vertical" flexItem sx={{ borderStyle: 'dashed' }} />}
              sx={{ py: 2 }}
            >
              <InvoiceAnalytic
                title="Total"
                total={tableData.length}
                percent={100}
                price={analytics.total}
                icon="solar:bill-list-bold-duotone"
                color={theme.palette.info.main}
              />

              <InvoiceAnalytic
                title="Paid"
                total={getInvoiceLength('paid')}
                percent={getPercentByStatus('paid')}
                price={analytics.paid}
                icon="solar:file-check-bold-duotone"
                color={theme.palette.success.main}
              />

              <InvoiceAnalytic
                title="Pending"
                total={getInvoiceLength('pending')}
                percent={getPercentByStatus('pending')}
                price={analytics.pending}
                icon="solar:sort-by-time-bold-duotone"
                color={theme.palette.warning.main}
              />

              <InvoiceAnalytic
                title="Overdue"
                total={getInvoiceLength('overdue')}
                percent={getPercentByStatus('overdue')}
                price={analytics.overdue}
                icon="solar:bell-bing-bold-duotone"
                color={theme.palette.error.main}
              />

              <InvoiceAnalytic
                title="Draft"
                total={getInvoiceLength('draft')}
                percent={getPercentByStatus('draft')}
                price={analytics.draft}
                icon="solar:file-corrupted-bold-duotone"
                color={theme.palette.text.secondary}
              />
            </Stack>
          </Scrollbar>
        </Card>

        <Card>
          <Tabs
            value={filters.status}
            onChange={handleFilterStatus}
            sx={{
              px: 2.5,
              boxShadow: `inset 0 -2px 0 0 ${alpha(theme.palette.grey[500], 0.08)}`,
            }}
          >
            {TABS.map((tab) => (
              <Tab
                key={tab.value}
                value={tab.value}
                label={tab.label}
                iconPosition="end"
                icon={
                  <Label
                    variant={
                      ((tab.value === 'all' || tab.value === filters.status) && 'filled') || 'soft'
                    }
                    color={tab.color}
                  >
                    {tab.count}
                  </Label>
                }
              />
            ))}
          </Tabs>

          <InvoiceTableToolbar
            filters={filters}
            onFilters={handleFilters}
            //
            dateError={dateError}
            serviceOptions={[]}
          />

          {canReset && (
            <InvoiceTableFiltersResult
              filters={filters}
              onFilters={handleFilters}
              //
              onResetFilters={handleResetFilters}
              //
              results={dataFiltered.length}
              sx={{ p: 2.5, pt: 0 }}
            />
          )}

          <TableContainer sx={{ position: 'relative', overflow: 'unset' }}>
            {/* <TableSelectedAction
              dense={table.dense}
              numSelected={table.selected.length}
              rowCount={tableData.length}
              onSelectAllRows={(checked) =>
                table.onSelectAllRows(
                  checked,
                  tableData.map((row) => row.id)
                )
              }
              action={
                <Stack direction="row">
                  <Tooltip title="Sent">
                    <IconButton color="primary">
                      <Iconify icon="iconamoon:send-fill" />
                    </IconButton>
                  </Tooltip>

                  <Tooltip title="Download">
                    <IconButton color="primary">
                      <Iconify icon="eva:download-outline" />
                    </IconButton>
                  </Tooltip>

                  <Tooltip title="Print">
                    <IconButton color="primary">
                      <Iconify icon="solar:printer-minimalistic-bold" />
                    </IconButton>
                  </Tooltip>

                  <Tooltip title="Delete">
                    <IconButton color="primary" onClick={confirm.onTrue}>
                      <Iconify icon="solar:trash-bin-trash-bold" />
                    </IconButton>
                  </Tooltip>
                </Stack>
              }
            /> */}

            <Scrollbar>
              <Table size={table.dense ? 'small' : 'medium'} sx={{ minWidth: 800 }}>
                <TableHeadCustom
                  order={table.order}
                  orderBy={table.orderBy}
                  headLabel={TABLE_HEAD}
                  rowCount={tableData.length}
                  numSelected={table.selected.length}
                  onSort={table.onSort}
                  onSelectAllRows={(checked) =>
                    table.onSelectAllRows(
                      checked,
                      tableData.map((row) => row.id)
                    )
                  }
                />

                <TableBody>
                  {dataFiltered
                    .slice(
                      table.page * table.rowsPerPage,
                      table.page * table.rowsPerPage + table.rowsPerPage
                    )
                    .map((row) => (
                      <InvoiceTableRow
                        key={row.id}
                        row={row}
                        selected={table.selected.includes(row.id)}
                        onSelectRow={() => table.onSelectRow(row.id)}
                        onViewRow={() => handleViewRow(row.id)}
                        onEditRow={() => handleEditRow(row.id)}
                        onCopyRow={() => handleCopyRow(row.id)}
                        onDeleteRow={async () => handleDeleteRow(row)}
                        onSendRow={() => {}}
                        onToggleCompose={() => handleToggleCompose(row)}
                      />
                    ))}

                  <TableEmptyRows
                    height={denseHeight}
                    emptyRows={emptyRows(table.page, table.rowsPerPage, tableData.length)}
                  />

                  <TableNoData notFound={notFound} />
                </TableBody>
              </Table>
            </Scrollbar>
          </TableContainer>

          <TablePaginationCustom
            count={dataFiltered.length}
            page={table.page}
            rowsPerPage={table.rowsPerPage}
            onPageChange={table.onChangePage}
            onRowsPerPageChange={table.onChangeRowsPerPage}
            //
            dense={table.dense}
            onChangeDense={table.onChangeDense}
          />
        </Card>
      </Container>

      {openCompose.value && (
        <MailCompose
          invoice={sendingInvoice}
          onCloseCompose={openCompose.onFalse}
          invoiceMutationKey={invoiceMutationKey}
        />
      )}

      {/* <ConfirmDialog
        open={confirm.value}
        onClose={confirm.onFalse}
        title="Delete"
        content={
          <>
            Are you sure want to delete <strong> {table.selected.length} </strong> items?
          </>
        }
        action={
          <Button
            variant="contained"
            color="error"
            onClick={() => {
              handleDeleteRows();
              confirm.onFalse();
            }}
          >
            Delete
          </Button>
        }
      /> */}
    </>
  );
}

// ----------------------------------------------------------------------

function applyFilter({
  inputData,
  comparator,
  filters,
  dateError,
}: {
  inputData: Invoice[];
  comparator: (a: any, b: any) => number;
  filters: InvoiceTableFilters;
  dateError: boolean;
}) {
  const { name, status, service, startDate, endDate } = filters;

  const stabilizedThis = inputData.map((el, index) => [el, index] as const);

  stabilizedThis.sort((a, b) => {
    const order = comparator(a[0], b[0]);
    if (order !== 0) return order;
    return a[1] - b[1];
  });

  inputData = stabilizedThis.map((el) => el[0]);

  if (name) {
    inputData = inputData.filter(
      (invoice) =>
        invoice.invoiceNumber.toLowerCase().indexOf(name.toLowerCase()) !== -1 ||
        invoice.invoiceTo.name.toLowerCase().indexOf(name.toLowerCase()) !== -1
    );
  }

  if (status !== 'all') {
    inputData = inputData.filter((invoice) => invoice.status === status);
  }

  if (service.length) {
    inputData = inputData.filter((invoice) =>
      invoice.items.some((filterItem) => service.includes(filterItem.service.id))
    );
  }

  if (!dateError) {
    if (startDate && endDate) {
      inputData = inputData.filter(
        (invoice) =>
          fTimestamp(invoice.createDate.getTime()) >= fTimestamp(startDate.getTime()) &&
          fTimestamp(invoice.createDate.getTime()) <= fTimestamp(endDate.getTime())
      );
    }
  }

  return inputData;
}
