import { EditFilled, SyncOutlined } from "@ant-design/icons";
import { useTreatmentsWithConfig } from "@splitsoftware/splitio-react";
import { Button, Card, Checkbox, Space } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { Link } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import { setModalContext } from "../../redux/modals/modals.actions";
import { selectAuthLevel, selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
import { DateFormatter, DateTimeFormatter } from "../../utils/DateFormatter";
import { onlyUnique } from "../../utils/arrayHelper";
import dayjs from "../../utils/day";
import { alphaSort, dateSort } from "../../utils/sorters";
import { HasRbacAccess } from "../rbac-wrapper/rbac-wrapper.component";
import TimeTicketEnterButton from "../time-ticket-enter-button/time-ticket-enter-button.component";
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
import LockWrapperComponent from "../lock-wrapper/lock-wrapper.component";
import UpsellComponent, { upsellEnum } from "../upsell/upsell.component";

const mapStateToProps = createStructuredSelector({
  bodyshop: selectBodyshop,
  authLevel: selectAuthLevel,
  currentUser: selectCurrentUser
});
const mapDispatchToProps = (dispatch) => ({
  setTimeTicketTaskContext: (context) => dispatch(setModalContext({ context: context, modal: "timeTicketTask" }))
});
export default connect(mapStateToProps, mapDispatchToProps)(TimeTicketList);

export function TimeTicketList({
  bodyshop,
  setTimeTicketTaskContext,
  authLevel,
  currentUser,
  disabled,
  loading,
  timetickets,
  refetch,
  techConsole,
  jobId,
  extra
}) {
  const [state, setState] = useState({
    sortedInfo: { columnKey: "date", order: "descend" },
    filteredInfo: { text: "" }
  });

  const { t } = useTranslation();
  const {
    treatments: { Enhanced_Payroll }
  } = useTreatmentsWithConfig({
    attributes: {},
    names: ["Enhanced_Payroll"],
    splitKey: bodyshop.imexshopid
  });

  const canEditCommittedTimeTickets = HasRbacAccess({ bodyshop, authLevel, action: "timetickets:editcommitted" });
  const canEditTimeTickets = HasRbacAccess({ bodyshop, authLevel, action: "timetickets:edit" });
  const canEditShiftTickets = HasRbacAccess({ bodyshop, authLevel, action: "timetickets:shiftedit" });

  const totals = useMemo(() => {
    if (timetickets)
      return timetickets.reduce(
        (acc, val) => {
          acc.productivehrs = acc.productivehrs + val.productivehrs;
          acc.actualhrs = acc.actualhrs + val.actualhrs;
          return acc;
        },
        { productivehrs: 0, actualhrs: 0 }
      );
    return { productivehrs: 0, actualhrs: 0 };
  }, [timetickets]);

  const isDisabled = (record) => {
    if (disabled === true || !record.id) return true;

    const isShiftTicket = !record.ciecacode;
    const isCommitted = record.committed_at;
    if (isShiftTicket) {
      return !(canEditShiftTickets && (!isCommitted || canEditCommittedTimeTickets));
    }

    return !(canEditTimeTickets && (!isCommitted || canEditCommittedTimeTickets));
  };

  const columns = [
    ...(Enhanced_Payroll.treatment === "on"
      ? [
          {
            title: t("timetickets.fields.committed"),
            dataIndex: "committed_at",
            key: "committed_at",
            render: (text, record) => <Checkbox disabled checked={record.committed_at} />
          }
        ]
      : []),

    {
      title: t("timetickets.fields.date"),
      dataIndex: "date",
      key: "date",
      sorter: (a, b) => dateSort(a.date, b.date),
      sortOrder: state.sortedInfo.columnKey === "date" && state.sortedInfo.order,
      render: (text, record) => <DateFormatter>{record.date}</DateFormatter>
    },
    {
      title: t("timetickets.fields.employee"),
      dataIndex: "employee",
      key: "employee",
      sorter: (a, b) => alphaSort(a.employee.last_name, b.employee.last_name),
      sortOrder: state.sortedInfo.columnKey === "employee" && state.sortedInfo.order,
      render: (text, record) => `${record.employee.first_name} ${record.employee.last_name}`,
      filters:
        timetickets
          .map((l) => l.employeeid)
          .filter(onlyUnique)
          .map((s) => {
            return {
              text: (() => {
                const emp = bodyshop.employees.find((e) => e.id === s);

                return `${emp?.first_name} ${emp?.last_name}`;
              })(), //
              value: [s]
            };
          }) || [],
      onFilter: (value, record) => value.includes(record.employeeid)
    },
    {
      title: t("timetickets.fields.cost_center"),
      dataIndex: "cost_center",
      key: "cost_center",
      sorter: (a, b) => alphaSort(a.cost_center, b.cost_center),
      render: (text, record) =>
        record.cost_center === "timetickets.labels.shift" ? t(record.cost_center) : record.cost_center,
      sortOrder: state.sortedInfo.columnKey === "cost_center" && state.sortedInfo.order,
      filters:
        timetickets
          .map((l) => l.cost_center)
          .filter(onlyUnique)
          .map((s) => {
            return {
              text: s === "timetickets.labels.shift" ? t(s) : s, //|| "No Status*",
              value: [s]
            };
          }) || [],
      onFilter: (value, record) => value.includes(record.cost_center)
    },
    ...(jobId
      ? []
      : [
          {
            title: t("jobs.fields.ro_number"),
            dataIndex: "ro_number",
            key: "ro_number",
            sorter: (a, b) => alphaSort(a.job && a.job.ro_number, b.job && b.job.ro_number),
            sortOrder: state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order,
            render: (text, record) =>
              record.job && <Link to={"/manage/jobs/" + record.job.id}>{record.job.ro_number || "N/A"}</Link>
          }
        ]),
    {
      title: t("timetickets.fields.productivehrs"),
      dataIndex: "productivehrs",
      key: "productivehrs",
      sorter: (a, b) => a.productivehrs - b.productivehrs,
      sortOrder: state.sortedInfo.columnKey === "productivehrs" && state.sortedInfo.order
    },
    ...(Enhanced_Payroll.treatment === "on"
      ? []
      : [
          {
            title: t("timetickets.fields.actualhrs"),
            dataIndex: "actualhrs",
            key: "actualhrs",
            sorter: (a, b) => a.actualhrs - b.actualhrs,
            sortOrder: state.sortedInfo.columnKey === "actualhrs" && state.sortedInfo.order
          }
        ]),
    {
      title: t("timetickets.fields.memo"),
      dataIndex: "memo",
      key: "memo",
      sorter: (a, b) => alphaSort(a.memo, b.memo),
      sortOrder: state.sortedInfo.columnKey === "memo" && state.sortedInfo.order,
      render: (text, record) => (record.memo?.startsWith("timetickets.labels") ? t(record.memo) : record.memo)
    },
    ...(Enhanced_Payroll.treatment === "on"
      ? [
          {
            title: t("timetickets.fields.task_name"),
            dataIndex: "task_name",
            key: "task_name",
            sorter: (a, b) => alphaSort(a.task_name, b.task_name),
            sortOrder: state.sortedInfo.columnKey === "task_name" && state.sortedInfo.order
          }
        ]
      : []),
    ...(Enhanced_Payroll.treatment === "on"
      ? []
      : [
          {
            title: t("timetickets.fields.clockon"),
            dataIndex: "clockon",
            key: "clockon",

            render: (text, record) => <DateTimeFormatter>{record.clockon}</DateTimeFormatter>
          },
          {
            title: t("timetickets.fields.clockoff"),
            dataIndex: "clockoff",
            key: "clockoff",

            render: (text, record) => <DateTimeFormatter>{record.clockoff}</DateTimeFormatter>
          },
          {
            title: t("timetickets.fields.clockhours"),
            dataIndex: "clockhours",
            key: "clockhours",
            render: (text, record) => {
              if (record.clockoff && record.clockon)
                return <div>{dayjs(record.clockoff).diff(dayjs(record.clockon), "hour", true).toFixed(2)}</div>;
              else {
                return null;
              }
            }
          }
        ]),
    {
      title: t("timetickets.fields.created_by"),
      dataIndex: "created_by",
      key: "created_by",
      sorter: (a, b) => alphaSort(a.created_by, b.created_by),
      sortOrder: state.sortedInfo.columnKey === "created_by" && state.sortedInfo.order,
      render: (text, record) => record.created_by
    },
    // {
    //   title: "Pay",
    //   dataIndex: "pay",
    //   key: "pay",
    //   render: (text, record) =>
    //     Dinero({ amount: Math.round(record.rate * 100) })
    //       .multiply(record.flat_rate ? record.productivehrs : record.actualhrs)
    //       .toFormat("$0.00"),
    // },
    {
      title: t("general.labels.actions"),
      dataIndex: "actions",
      key: "actions",
      render: (text, record) => (
        <Space wrap>
          {techConsole && (
            <TimeTicketEnterButton
              actions={{ refetch }}
              context={{ id: record.id, timeticket: record }}
              disabled={!record.job || disabled}
            >
              <EditFilled />
            </TimeTicketEnterButton>
          )}
          {!techConsole && (
            <TimeTicketEnterButton
              actions={{ refetch }}
              context={{
                id: record.id,
                timeticket: record
              }}
              disabled={isDisabled(record)}
            >
              <EditFilled />
            </TimeTicketEnterButton>
          )}
        </Space>
      )
    }
  ];

  const handleTableChange = (pagination, filters, sorter) => {
    setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
  };

  const hasTimeTicketsAccess = HasFeatureAccess({ bodyshop, featureName: "timetickets" });

  return (
    <Card
      title={t("timetickets.labels.timetickets")}
      extra={
        <Space wrap>
          {jobId && bodyshop.md_tasks_presets.enable_tasks && (
            <Button
              disabled={disabled || !hasTimeTicketsAccess}
              onClick={() => {
                setTimeTicketTaskContext({
                  actions: { refetch: refetch },
                  context: { jobid: jobId }
                });
              }}
            >
              <LockWrapperComponent featureName="timetickets">
                {t("timetickets.actions.claimtasks")}
              </LockWrapperComponent>
            </Button>
          )}
          {jobId &&
            (techConsole ? null : (
              <TimeTicketEnterButton
                actions={{ refetch }}
                context={{
                  jobId: jobId,
                  created_by: currentUser.displayName
                    ? currentUser.email.concat(" | ", currentUser.displayName)
                    : currentUser.email
                }}
                disabled={disabled || !hasTimeTicketsAccess}
              >
                <LockWrapperComponent featureName="timetickets">{t("timetickets.actions.enter")}</LockWrapperComponent>
              </TimeTicketEnterButton>
            ))}
          {extra}
          <Button
            onClick={async () => {
              refetch();
            }}
            icon={<SyncOutlined />}
          />
        </Space>
      }
    >
      <ResponsiveTable
        loading={loading}
        columns={columns}
        mobileColumnKeys={["ro_number", "date", "actions", "committed_at"]}
        rowKey="id"
        scroll={{
          x: true
        }}
        dataSource={hasTimeTicketsAccess ? timetickets : []}
        onChange={handleTableChange}
        summary={() => {
          if (Enhanced_Payroll.treatment === "on") return null;
          if (Enhanced_Payroll.treatment === "off")
            return (
              <ResponsiveTable.Summary.Row>
                <ResponsiveTable.Summary.Cell>{t("general.labels.totals")}</ResponsiveTable.Summary.Cell>
                <ResponsiveTable.Summary.Cell />
                <ResponsiveTable.Summary.Cell />
                <ResponsiveTable.Summary.Cell>{totals.productivehrs.toFixed(1)}</ResponsiveTable.Summary.Cell>
                <ResponsiveTable.Summary.Cell>{totals.actualhrs.toFixed(1)}</ResponsiveTable.Summary.Cell>
                <ResponsiveTable.Summary.Cell>
                  {totals.actualhrs === 0 || !totals.actualhrs
                    ? "∞"
                    : `${((totals.productivehrs / totals.actualhrs) * 100).toFixed(
                        2
                      )}% ${t("timetickets.labels.efficiency")}`}
                </ResponsiveTable.Summary.Cell>
                <ResponsiveTable.Summary.Cell />
                <ResponsiveTable.Summary.Cell />
                <ResponsiveTable.Summary.Cell />
              </ResponsiveTable.Summary.Row>
            );
        }}
        locale={{
          ...(!hasTimeTicketsAccess && {
            emptyText: (
              <Card>
                <UpsellComponent upsell={upsellEnum().timetickets.general} />
              </Card>
            )
          })
        }}
      />
    </Card>
  );
}
