import { Card, Col, Row, Table } from "antd";
import _ from "lodash";
import moment from "moment";
import React, { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { onlyUnique } from "../../utils/arrayHelper";
import { alphaSort } from "../../utils/sorters";
import { TemplateList } from "../../utils/TemplateConstants";
import PrintWrapperComponent from "../print-wrapper/print-wrapper.component";

const mapStateToProps = createStructuredSelector({
  bodyshop: selectBodyshop,
});
const mapDispatchToProps = (dispatch) => ({
  //setUserLanguage: language => dispatch(setUserLanguage(language))
});

export function TimeTicketsSummaryEmployees({
  bodyshop,
  loading,
  timetickets,
  startDate,
  endDate,
}) {
  //Group everything by employee
  //Then sum the individual time TimeTicketsSummary.

  //Calculate job based tickets.
  const jobTicketsByEmployee = {};
  timetickets
    .filter((i) => i.cost_center !== "timetickets.labels.shift")
    .map((tt) => {
      if (!!!jobTicketsByEmployee[tt.employeeid]) {
        jobTicketsByEmployee[tt.employeeid] = [];
      }
      jobTicketsByEmployee[tt.employeeid].push(tt);
      return null;
    });
  const jobTickets = Object.keys(jobTicketsByEmployee).map(function (key) {
    return {
      jobKey: key,
      employee: jobTicketsByEmployee[key][0].employee,
      tickets: jobTicketsByEmployee[key],
    };
  });

  //Calculate shift based tickets.
  const shiftTicketsByEmployee = {};
  timetickets
    .filter((i) => i.cost_center === "timetickets.labels.shift")
    .map((tt) => {
      if (!!!shiftTicketsByEmployee[tt.employeeid]) {
        shiftTicketsByEmployee[tt.employeeid] = [];
      }
      shiftTicketsByEmployee[tt.employeeid].push(tt);
      return null;
    });
  const shiftTickets = Object.keys(shiftTicketsByEmployee).map(function (key) {
    return {
      employee: shiftTicketsByEmployee[key][0].employee,
      tickets: shiftTicketsByEmployee[key],
    };
  });

  return (
    <Row gutter={[16, 16]}>
      <Col span={24}>
        <JobRelatedTicketsTable
          loading={loading}
          jobTickets={jobTickets}
          startDate={startDate}
          endDate={endDate}
        />
      </Col>
      <Col span={24}>
        <ShiftRelatedTicketsTable
          loading={loading}
          shiftTickets={shiftTickets}
          startDate={startDate}
          endDate={endDate}
        />
      </Col>
    </Row>
  );
}
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(TimeTicketsSummaryEmployees);

const JobRelatedTicketsTable = ({
  loading,
  jobTickets,
  startDate,
  endDate,
}) => {
  const Templates = TemplateList();
  const { t } = useTranslation();
  const [state, setState] = useState({
    sortedInfo: {},
  });
  const data = useMemo(() => {
    return _.flatten(
      jobTickets.map((item, idx) => {
        const employeeCostCenters = item.tickets
          .map((i) => i.cost_center)
          .filter(onlyUnique);

        return employeeCostCenters.map((costCenter) => {
          const actHrs = item.tickets
            .filter((ticket) => ticket.cost_center === costCenter)
            .reduce((acc, val) => acc + val.actualhrs, 0);

          const prodHrs = item.tickets
            .filter((ticket) => ticket.cost_center === costCenter)
            .reduce((acc, val) => acc + val.productivehrs, 0);

          const clockHrs = item.tickets
            .filter((ticket) => ticket.cost_center === costCenter)
            .reduce((acc, val) => {
              if (!!val.clockoff && !!val.clockon)
                return (
                  acc +
                  moment(val.clockoff).diff(moment(val.clockon), "hours", true)
                );
              return acc;
            }, 0);

          return {
            id: `${item.jobKey}${costCenter}`,
            item,
            actHrs,
            prodHrs,
            clockHrs,
          };
        });
      })
    );
  }, [jobTickets]);

  const columns = [
    {
      title: t("employees.labels.name"),
      dataIndex: "empname",
      key: "empname",
      sorter: (a, b) => alphaSort(a.empname, b.empname),
      sortOrder:
        state.sortedInfo.columnKey === "empname" && state.sortedInfo.order,
      render: (text, record) =>
        `${record.item.employee.first_name} ${record.item.employee.last_name}`,
    },
    {
      title: t("timetickets.fields.actualhrs"),
      dataIndex: "actHrs",
      key: "actHrs",
      sorter: (a, b) => a.actHrs - b.actHrs,
      sortOrder:
        state.sortedInfo.columnKey === "actHrs" && state.sortedInfo.order,
    },
    {
      title: t("timetickets.fields.productivehrs"),
      dataIndex: "prodHrs",
      key: "prodHrs",
      sorter: (a, b) => a.prodHrs - b.prodHrs,
      sortOrder:
        state.sortedInfo.columnKey === "prodHrs" && state.sortedInfo.order,
    },
    {
      title: t("timetickets.fields.efficiency"),
      dataIndex: "total",
      key: "total",
      sorter: (a, b) => a.total - b.total,
      sortOrder:
        state.sortedInfo.columnKey === "total" && state.sortedInfo.order,
      render: (text, record) =>
        record.actHrs === 0 || !record.actHrs
          ? "∞"
          : ((record.prodHrs / record.actHrs) * 100).toFixed(2),
    },
    {
      title: t("timetickets.fields.clockhours"),
      dataIndex: "clockHrs",
      key: "clockHrs",
      sorter: (a, b) => a.clockHrs - b.clockHrs,
      sortOrder:
        state.sortedInfo.columnKey === "clockHrs" && state.sortedInfo.order,
      render: (text, record) => record.clockHrs.toFixed(2),
    },
    {
      title: t("general.labels.actions"),
      dataIndex: "actions",
      key: "actions",
      render: (text, record) => (
        <PrintWrapperComponent
          templateObject={{
            name: Templates.timetickets_employee.key,
            variables: {
              id: record.item.employee.id,
              start: startDate,
              end: endDate,
            },
          }}
          messageObject={{ subject: Templates.timetickets_employee.subject }}
        />
      ),
    },
  ];

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

  return (
    <Card title={t("timetickets.labels.jobhours")}>
      <Table
        loading={loading}
        scroll={{
          x: true, // y: "50rem"
        }}
        columns={columns}
        rowKey="id"
        dataSource={data}
        onChange={handleTableChange}
      />
    </Card>
  );
};

const ShiftRelatedTicketsTable = ({
  loading,
  shiftTickets,
  startDate,
  endDate,
}) => {
  const Templates = TemplateList();
  const { t } = useTranslation();
  const [state, setState] = useState({
    sortedInfo: {},
  });
  const data = useMemo(() => {
    return shiftTickets.map((item) => {
      const clockHrs = item.tickets.reduce((acc, val) => {
        if (!!val.clockoff && !!val.clockon)
          return (
            acc + moment(val.clockoff).diff(moment(val.clockon), "hours", true)
          );
        return acc;
      }, 0);

      return { id: item.employee.id, item, clockHrs };
    });
  }, [shiftTickets]);

  const columns = [
    {
      title: t("employees.labels.name"),
      dataIndex: "empname",
      key: "empname",
      sorter: (a, b) => alphaSort(a.empname, b.empname),
      sortOrder:
        state.sortedInfo.columnKey === "empname" && state.sortedInfo.order,
      render: (text, record) =>
        `${record.item.employee.first_name} ${record.item.employee.last_name}`,
    },

    {
      title: t("timetickets.fields.clockhours"),
      dataIndex: "clockHrs",
      key: "clockHrs",
      sorter: (a, b) => a.clockHrs - b.clockHrs,
      sortOrder:
        state.sortedInfo.columnKey === "clockHrs" && state.sortedInfo.order,
      render: (text, record) => record.clockHrs.toFixed(2),
    },
    {
      title: t("general.labels.actions"),
      dataIndex: "actions",
      key: "actions",
      render: (text, record) => (
        <PrintWrapperComponent
          templateObject={{
            name: Templates.attendance_employee.key,
            variables: {
              id: record.item.employee.id,
              start: startDate,
              end: endDate,
            },
          }}
          messageObject={{ subject: Templates.attendance_employee.subject }}
        />
      ),
    },
  ];

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

  return (
    <Card title={t("timetickets.labels.clockhours")}>
      <Table
        loading={loading}
        scroll={{
          x: true, // y: "50rem"
        }}
        columns={columns}
        rowKey="id"
        dataSource={data}
        onChange={handleTableChange}
      />
    </Card>
  );
};
