/* eslint-disable jsx-a11y/anchor-is-valid */

import {
  Link,
  Input,
  Table,
  Sheet,
  IconButton,
  Typography,
  Box,
  Button,
} from "@mui/joy";
import CustomAlert from "~/components/CustomAlert";
import { useState } from "react";
import * as Icon from "react-feather";
import { api } from "~/utils/api";

function descendingComparator<T>(a: T, b: T, orderBy: keyof T) {
  if (b[orderBy] < a[orderBy]) {
    return -1;
  }
  if (b[orderBy] > a[orderBy]) {
    return 1;
  }
  return 0;
}

type Order = "asc" | "desc";

function getComparator<Key extends keyof any>(
  order: Order,
  orderBy: Key
): (
  a: { [key in Key]: number | string },
  b: { [key in Key]: number | string }
) => number {
  return order === "desc"
    ? (a, b) => descendingComparator(a, b, orderBy)
    : (a, b) => -descendingComparator(a, b, orderBy);
}

function stableSort<T>(
  array: readonly T[],
  comparator: (a: T, b: T) => number
) {
  const stabilizedThis = array.map((el, index) => [el, index] as [T, number]);
  stabilizedThis.sort((a, b) => {
    const order = comparator(a[0], b[0]);
    if (order !== 0) {
      return order;
    }
    return a[1] - b[1];
  });
  return stabilizedThis.map((el) => el[0]);
}

const timeOptions = {
  timeZone: "America/Sao_Paulo",
};

const cancelledStyle = {
  textDecoration: "line-through",
  color: "red",
};

function NestedList({ sale, cancelSale }) {
  const [open, setOpen] = useState(false);

  const totalQuantity = sale.sale_items.reduce(
    (acc, curr) => acc + curr.quantity,
    0
  );
  const totalCost = sale.sale_items.reduce(
    (acc, curr) => acc + curr.product.cost,
    0
  );
  const totalValue = sale.sale_items.reduce(
    (acc, curr) => acc + curr.product.price,
    0
  );

  let discountAbsolute = 0;
  if (sale.discount_percent) {
    discountAbsolute = (sale.total_sale * sale.discount_percent) / 100;
  }

  return (
    <>
      <tr key={sale.id} style={sale.cancelled ? cancelledStyle : {}}>
        <td>
          <Typography fontWeight='md'>{sale.id}</Typography>
        </td>
        <td>
          {sale.created_at.toLocaleDateString("pt-BR", timeOptions)}{" "}
          {sale.created_at.toLocaleTimeString("pt-BR", timeOptions)}
        </td>
        <td>
          {sale.total_sale.toLocaleString("pt-BR", {
            style: "currency",
            currency: "BRL",
          })}
        </td>
        <td>
          {sale.discount_percent
            ? `${sale.discount_percent}% (R$ ${discountAbsolute.toLocaleString(
                "pt-BR",
                {
                  style: "currency",
                  currency: "BRL",
                }
              )})`
            : "N/A"}
        </td>
        <td>
          {sale.total_discount
            ? sale.total_discount.toLocaleString("pt-BR", {
                style: "currency",
                currency: "BRL",
              })
            : sale.total_sale.toLocaleString("pt-BR", {
                style: "currency",
                currency: "BRL",
              })}
        </td>
        <td>
          {sale.total_paid.toLocaleString("pt-BR", {
            style: "currency",
            currency: "BRL",
          })}
        </td>

        <td>
          <IconButton
            aria-label='expand row'
            variant='plain'
            color='neutral'
            size='sm'
            onClick={() => {
              setOpen(!open);
            }}
          >
            {open ? <Icon.ArrowUp /> : <Icon.ArrowDown />}
          </IconButton>
        </td>
        <td>
          {!sale.cancelled && (
            <Box justifyContent='center'>
              <Button
                variant='solid'
                color='danger'
                onClick={() => {
                  cancelSale(sale.id);
                }}
              >
                <Icon.XSquare size={18} />
              </Button>
            </Box>
          )}
        </td>
      </tr>

      <tr>
        <td style={{ height: 0, padding: 0 }} colSpan={8}>
          {open && (
            <Table
              borderAxis='bothBetween'
              size='sm'
              aria-label='purchases'
              sx={{
                "& > thead > tr > th:nth-of-type(n + 3), & > tbody > tr > td:nth-of-type(n + 3)":
                  { textAlign: "left" },
                "--TableCell-paddingX": "0.5rem",
              }}
            >
              <thead>
                <tr>
                  <th>ID</th>
                  <th>Cod. Barras</th>
                  <th>Nome</th>
                  <th>Quantidade</th>
                  <th>Custo (R$)</th>
                  <th>Preço Venda (R$)</th>
                </tr>
              </thead>
              <tbody>
                {sale.sale_items.map((item) => (
                  <tr key={item.product.barcode}>
                    <td>{item.product.id}</td>
                    <td>{item.product.barcode}</td>
                    <td>{item.product.name}</td>
                    <td>
                      <Typography textAlign='right'>{item.quantity}</Typography>
                    </td>
                    <td>
                      <Typography textAlign='right'>
                        {item.product.cost.toLocaleString("pt-BR", {
                          style: "currency",
                          currency: "BRL",
                        })}
                      </Typography>
                    </td>
                    <td>
                      <Typography textAlign='right'>
                        {item.product.price.toLocaleString("pt-BR", {
                          style: "currency",
                          currency: "BRL",
                        })}
                      </Typography>
                    </td>
                  </tr>
                ))}
                <tr>
                  <td colSpan={3}>
                    <Typography
                      level='body2'
                      textAlign='left'
                      textColor='text.primary'
                    >
                      Total
                    </Typography>
                  </td>
                  <td colSpan={1}>
                    <Typography
                      level='body2'
                      textAlign='right'
                      textColor='text.primary'
                    >
                      {totalQuantity}
                    </Typography>
                  </td>
                  <td colSpan={1}>
                    <Typography
                      level='body2'
                      textAlign='right'
                      textColor='text.primary'
                    >
                      {totalCost.toLocaleString("pt-BR", {
                        style: "currency",
                        currency: "BRL",
                      })}
                    </Typography>
                  </td>
                  <td colSpan={1}>
                    <Typography
                      level='body2'
                      textAlign='right'
                      textColor='text.primary'
                    >
                      {totalValue.toLocaleString("pt-BR", {
                        style: "currency",
                        currency: "BRL",
                      })}
                    </Typography>
                  </td>
                </tr>
              </tbody>
            </Table>
          )}
        </td>
      </tr>
    </>
  );
}

export default function SaleTable() {
  const [order, setOrder] = useState<Order>("desc");

  const salesQuery = api.sale.getSales.useQuery(undefined, {
    refetchOnWindowFocus: false,
  });

  const createAlert = (settings) => {
    setAlert({ ...settings, open: true });
  };

  const [customAlert, setAlert] = useState({
    open: false,
    type: "success",
    text: "",
    duration: 6000,
  });

  const cancelSaleMutation = api.sale.cancelSale.useMutation({
    onSuccess: (data) => {
      createAlert({
        type: "success",
        text: "Venda cancelada com sucesso!",
        duration: 6000,
      });
    },
    onError: (error) => {
      createAlert({
        type: "error",
        text: error.message,
        duration: 6000,
      });
    },
    onSettled: () => salesQuery.refetch(),
  });

  const cancelSale = (sale_id) => {
    if (confirm("Você tem certeza que deseja cancelar a venda?")) {
      cancelSaleMutation.mutate({
        sale_id,
      });
    }
  };

  return (
    <>
      <CustomAlert customAlert={customAlert} setAlert={setAlert} />
      <Sheet
        className='SearchAndFilters-mobile'
        sx={{
          display: {
            xs: "flex",
            sm: "none",
          },
          my: 1,
          gap: 1,
        }}
      >
        <Input
          size='sm'
          placeholder='Search'
          startDecorator={<Icon.Search />}
          sx={{ flexGrow: 1 }}
        />
      </Sheet>
      <Sheet
        className='OrderTableContainer'
        variant='outlined'
        sx={{
          width: "100%",
          borderRadius: "md",
          flex: 1,
          overflow: "auto",
          minHeight: 0,
        }}
      >
        <Table
          aria-labelledby='tableTitle'
          stickyHeader
          sx={{
            "--TableCell-headBackground": (theme) =>
              theme.vars.palette.background.level1,
            "--Table-headerUnderlineThickness": "1px",
            "--TableRow-hoverBackground": (theme) =>
              theme.vars.palette.background.level1,
          }}
        >
          <thead>
            <tr>
              <th style={{ width: 80, padding: 12 }}>
                <Link
                  underline='none'
                  color='primary'
                  component='button'
                  onClick={() => setOrder(order === "asc" ? "desc" : "asc")}
                  fontWeight='lg'
                  endDecorator={<Icon.ArrowDown />}
                  sx={{
                    "& svg": {
                      transition: "0.2s",
                      transform:
                        order === "desc" ? "rotate(0deg)" : "rotate(180deg)",
                    },
                  }}
                >
                  #
                </Link>
              </th>
              <th style={{ padding: 12 }}>Data</th>
              <th style={{ padding: 12 }}>Total Produtos</th>
              <th style={{ padding: 12 }}>Desconto</th>
              <th style={{ padding: 12 }}>Total a Pagar</th>
              <th style={{ padding: 12 }}>Total Pago</th>
              <th style={{ width: 80, padding: 12 }}>Detalhes</th>
              <th style={{ width: 80, padding: 12 }}>Cancelar</th>
            </tr>
          </thead>
          <tbody>
            {salesQuery.isSuccess &&
              stableSort(salesQuery.data.sales, getComparator(order, "id")).map(
                (sale, idx) => (
                  <NestedList key={idx} sale={sale} cancelSale={cancelSale} />
                )
              )}
          </tbody>
        </Table>
      </Sheet>
    </>
  );
}
