import React, { useCallback, useState } from "react";

import DeleteOutlineOutlinedIcon from "@mui/icons-material/DeleteOutlineOutlined";
import { TableBody, TableRow } from "@mui/material";
import IconButton from "@mui/material/IconButton";
import Typography from "@mui/material/Typography";

import { DateTime } from "luxon";
import { useSnackbar } from "notistack";

import Table from "../../../components/Table";
import { TableCell } from "../../../components/Table/TableCell";
import TableHeading from "../../../components/Table/TableHeading";
import TableCard from "../../../components/TableCard";
import TableCardHeader from "../../../components/TableCardHeader";
import { useApi } from "../../../contexts/ApiContext";
import { useDialog } from "../../../contexts/DialogContext";
import { useI18n } from "../../../contexts/I18nContext";
import { useUser } from "../../../contexts/UserContext";
import { ContribComponent, LimitOffset } from "../../../types";
import { hasPermission } from "../../../util/has_permission";
import { getHumanReadablePaymentMethod } from "../../pos/utils/getHumanReadablePaymentMethod";
import { PaymentMethod } from "../types/paymentMethod";
import { paymentMethodMask } from "../utils/paymentMethodMask";

const PaymentMethodsCard: ContribComponent<LimitOffset<PaymentMethod>> = ({
  data: { next: _next, previous: _previous, results: initialResults },
  params,
  refresh,
}) => {
  const results = initialResults.filter((method) => !method.is_revoked);

  const openDialog = useDialog();
  const api = useApi();
  const { t } = useI18n();
  const { user } = useUser();
  const { enqueueSnackbar } = useSnackbar();

  const isEditable = hasPermission(user, "pos.delete_paymenttoken") && results.length > 0;
  const [isEditing, setIsEditing] = useState(false);

  const { membership_number } = params as { membership_number?: number };

  const revoke = useCallback(
    async (token_id: number) => {
      if (
        await openDialog(
          t("Revoke Payment Method"),
          t("Are you sure you want to revoke this member's payment method?"),
          {
            ok: t("Yes, revoke"),
            cancel: t("Cancel"),
          },
        )
      ) {
        const action = api.operations["pos.contrib:member-paymenttoken-revoke"];
        if (!action) {
          throw new Error('Invalid action "pos.contrib:member-paymenttoken-revoke".');
        }

        const response = await action.call({ params: { membership_number, token_id } });
        if (response.ok) {
          refresh();
          setIsEditing(false);
          enqueueSnackbar(t("Payment method revoked"), { variant: "success" });
        } else {
          console.error("[REVOKE_PAYMENT_METHOD]", response);
          enqueueSnackbar(t("Failed to revoke payment method"), { variant: "error" });
        }
      }
    },
    [api, results],
  );

  return (
    <TableCard>
      <TableCardHeader
        isEditable={isEditable}
        title="Payment Methods"
        toggled={isEditing}
        onChange={setIsEditing}
      />
      <Table count={results.length}>
        <TableBody
          sx={{ ".MuiTableRow-root:last-child > .MuiTableCell-root": { borderBottom: "none" } }}
        >
          {results.length > 0 ? (
            results.map((method) => (
              <TableRow key={method.id}>
                <TableHeading>
                  {getHumanReadablePaymentMethod(method.method)?.name ?? method.method}
                </TableHeading>
                <TableCell>{paymentMethodMask(method)}</TableCell>
                <TableCell align="right">
                  {DateTime.fromISO(method.expiry_date).toFormat("MM/yy")}
                </TableCell>
                {isEditable && isEditing && (
                  <TableCell align="right" padding="none" sx={{ width: 64 }}>
                    <IconButton onClick={() => revoke(method.id)}>
                      <DeleteOutlineOutlinedIcon fontSize="small" />
                    </IconButton>
                  </TableCell>
                )}
              </TableRow>
            ))
          ) : (
            <Typography color="text.disabled" fontStyle="italic" m="0 1em 1em 1em">
              No payment methods registered
            </Typography>
          )}
        </TableBody>
      </Table>
    </TableCard>
  );
};

export default PaymentMethodsCard;
