import { useLazyQuery } from "@apollo/client/react";
import { useTreatmentsWithConfig } from "@splitsoftware/splitio-react";
import { Button, Card, Col, DatePicker, Form, Input, Radio, Row, Typography } from "antd";
import _ from "lodash";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
import { QUERY_ACTIVE_EMPLOYEES, QUERY_ACTIVE_EMPLOYEES_WITH_EMAIL } from "../../graphql/employees.queries";
import { QUERY_ALL_VENDORS } from "../../graphql/vendors.queries";
import { selectReportCenter } from "../../redux/modals/modals.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors";
import DatePickerRanges from "../../utils/DatePickerRanges";
import { DMS_MAP, getDmsMode } from "../../utils/dmsUtils";
import { GenerateDocument } from "../../utils/RenderTemplate";
import { TemplateList } from "../../utils/TemplateConstants";
import dayjs from "../../utils/day";
import EmployeeSearchSelectEmail from "../employee-search-select/employee-search-select-email.component";
import EmployeeSearchSelect from "../employee-search-select/employee-search-select.component";
import BlurWrapperComponent from "../feature-wrapper/blur-wrapper.component";
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
import LockWrapperComponent from "../lock-wrapper/lock-wrapper.component";
import VendorSearchSelect from "../vendor-search-select/vendor-search-select.component";
import ReportCenterModalFiltersSortersComponent from "./report-center-modal-filters-sorters-component";
import "./report-center-modal.styles.scss";

const mapStateToProps = createStructuredSelector({
  reportCenterModal: selectReportCenter,
  bodyshop: selectBodyshop
});
const mapDispatchToProps = () => ({
  //setUserLanguage: language => dispatch(setUserLanguage(language))
});
export default connect(mapStateToProps, mapDispatchToProps)(ReportCenterModalComponent);

export function ReportCenterModalComponent({ reportCenterModal, bodyshop }) {
  const [form] = Form.useForm();
  const [search, setSearch] = useState("");
  const {
    treatments: { Enhanced_Payroll, ADPPayroll }
  } = useTreatmentsWithConfig({
    attributes: {},
    names: ["Enhanced_Payroll", "ADPPayroll"],
    splitKey: bodyshop.imexshopid
  });
  const notification = useNotification();

  const [loading, setLoading] = useState(false);
  const { t } = useTranslation();
  const Templates = TemplateList("report_center");
  const dmsMode = getDmsMode(bodyshop, "off");
  const isReynoldsMode = dmsMode === DMS_MAP.reynolds;
  const ReportsList = Object.keys(Templates)
    .map((key) => Templates[key])
    .filter((temp) => {
      const enhancedPayrollOn = Enhanced_Payroll.treatment === "on";
      const adpPayrollOn = ADPPayroll.treatment === "on";

      if (isReynoldsMode && temp.excludedDmsModes?.includes(dmsMode)) {
        return false;
      }

      if (enhancedPayrollOn && adpPayrollOn) {
        return temp.enhanced_payroll !== false || temp.adp_payroll !== false;
      }
      if (enhancedPayrollOn) {
        return temp.enhanced_payroll !== false && temp.adp_payroll !== true;
      }
      if (adpPayrollOn) {
        return temp.adp_payroll !== false && temp.enhanced_payroll !== true;
      }

      return temp.enhanced_payroll !== true && temp.adp_payroll !== true;
    });

  const { open } = reportCenterModal;

  const [callVendorQuery, { data: vendorData, called: vendorCalled }] = useLazyQuery(QUERY_ALL_VENDORS, {
    skip: !(open && Templates[form.getFieldValue("key")] && Templates[form.getFieldValue("key")].idtype)
  });

  const [callEmployeeQuery, { data: employeeData, called: employeeCalled }] = useLazyQuery(QUERY_ACTIVE_EMPLOYEES, {
    skip: !(open && Templates[form.getFieldValue("key")] && Templates[form.getFieldValue("key")].idtype)
  });

  const [callEmployeeWithEmailQuery, { data: employeeWithEmailData, called: employeeWithEmailCalled }] = useLazyQuery(
    QUERY_ACTIVE_EMPLOYEES_WITH_EMAIL,
    {
      skip: !(open && Templates[form.getFieldValue("key")] && Templates[form.getFieldValue("key")].idtype)
    }
  );

  const handleFinish = async (values) => {
    setLoading(true);
    const start = values.dates ? values.dates[0] : null;
    const end = values.dates ? values.dates[1] : null;
    const { id } = values;

    const templateConfig = {
      name: values.key,
      variables: {
        ...(start ? { start: dayjs(start).startOf("day").format("YYYY-MM-DD") } : {}),
        ...(end ? { end: dayjs(end).endOf("day").format("YYYY-MM-DD") } : {}),
        ...(start ? { starttz: dayjs(start).startOf("day") } : {}),
        ...(end ? { endtz: dayjs(end).endOf("day") } : {}),

        ...(id ? { id: id } : {})
      },
      filters: values.filters,
      sorters: values.sorters
    };

    if (_.isString(values.defaultSorters) && !_.isEmpty(values.defaultSorters)) {
      templateConfig.defaultSorters = JSON.parse(values.defaultSorters);
    }

    await GenerateDocument(
      templateConfig,
      {
        to: values.to,
        subject: Templates[values.key]?.subject
      },
      values.sendbytext === "text"
        ? values.sendbytext
        : values.sendbyexcel === "excel"
          ? "x"
          : values.sendby === "email"
            ? "e"
            : "p",
      id,
      notification
    );
    setLoading(false);
  };

  const FilteredReportsList =
    search !== "" ? ReportsList.filter((r) => r.title.toLowerCase().includes(search.toLowerCase())) : ReportsList;

  //Group it, create cards, and then filter out.

  const grouped = _.groupBy(FilteredReportsList, "group");

  const groupExcludeKeyFilter = [
    ...(!HasFeatureAccess({ featureName: "bills", bodyshop }) ? [{ key: "purchases", featureName: "bills" }] : []),
    ...(!HasFeatureAccess({ featureName: "timetickets", bodyshop })
      ? [{ key: "payroll", featureName: "timetickets" }]
      : [])
  ];

  //TODO: Find a way to filter out / blur on demand.
  return (
    <div className="report-center-modal">
      <Form onFinish={handleFinish} autoComplete={"off"} layout="vertical" form={form}>
        <Input.Search onChange={(e) => setSearch(e.target.value)} value={search} enterButton />
        <Form.Item name="defaultSorters" hidden>
          <Input type="hidden" />
        </Form.Item>
        <Form.Item
          name="key"
          label={t("reportcenter.labels.key")}
          //  className="radio-group-columns"
          rules={[
            {
              required: true
              //message: t("general.validation.required"),
            }
          ]}
        >
          <Radio.Group>
            <Row gutter={[16, 16]}>
              {Object.keys(grouped)
                //.filter((key) => !groupExcludeKeyFilter.includes(key))
                .map((key) => (
                  <Col xs={24} sm={12} md={Object.keys(grouped).length === 1 ? 24 : 8} key={key}>
                    <Card.Grid
                      style={{
                        width: "100%",
                        height: "100%",
                        maxHeight: "33vh",
                        overflowY: "scroll",
                        minWidth: "200px"
                      }}
                    >
                      <Typography.Title level={4}>{t(`reportcenter.labels.groups.${key}`)}</Typography.Title>
                      {groupExcludeKeyFilter.find((g) => g.key === key) ? (
                        <BlurWrapperComponent
                          featureName={groupExcludeKeyFilter.find((g) => g.key === key).featureName}
                        >
                          <ul
                            style={{
                              listStyleType: "none",
                              columns: grouped[key].length > 4 ? "2 auto" : "1",
                              padding: 0,
                              margin: 0
                            }}
                          >
                            {grouped[key].map((item) => (
                              <li key={item.key}>
                                <Radio key={item.key} value={item.key}>
                                  {item.title}
                                </Radio>
                              </li>
                            ))}
                          </ul>
                        </BlurWrapperComponent>
                      ) : (
                        <ul
                          style={{
                            listStyleType: "none",
                            columns: grouped[key].length > 4 ? "2 auto" : "1",
                            padding: 0,
                            margin: 0
                          }}
                        >
                          {grouped[key].map((item) =>
                            item.featureNameRestricted ? (
                              <li key={item.key}>
                                <LockWrapperComponent featureName={item.featureNameRestricted}>
                                  <Radio key={item.key} value={item.key}>
                                    {item.title}
                                  </Radio>
                                </LockWrapperComponent>
                              </li>
                            ) : (
                              <li key={item.key}>
                                <Radio key={item.key} value={item.key}>
                                  {item.title}
                                </Radio>
                              </li>
                            )
                          )}
                        </ul>
                      )}
                    </Card.Grid>
                  </Col>
                ))}
            </Row>
          </Radio.Group>
        </Form.Item>
        <Form.Item style={{ margin: 0, padding: 0 }} dependencies={["key"]}>
          {() => {
            const key = form.getFieldValue("key");
            if (!key) return null;
            //Kind of Id
            const rangeFilter = Templates[key] && Templates[key].rangeFilter;
            if (!rangeFilter) return null;
            return (
              <div>
                {t("reportcenter.labels.filterson", {
                  object: rangeFilter.object,
                  field: rangeFilter.field
                })}
              </div>
            );
          }}
        </Form.Item>
        <ReportCenterModalFiltersSortersComponent form={form} bodyshop={bodyshop} />
        <Form.Item style={{ margin: 0, padding: 0 }} dependencies={["key"]}>
          {() => {
            const key = form.getFieldValue("key");
            const currentId = form.getFieldValue("id");
            if (!key) return null;
            //Kind of Id
            const idtype = Templates[key] && Templates[key].idtype;
            if (!idtype && currentId) {
              form.setFieldsValue({ id: null });
              return null;
            }
            if (!vendorCalled && idtype === "vendor") callVendorQuery({ variables: {} });
            if (!employeeCalled && idtype === "employee") callEmployeeQuery({ variables: {} });
            if (!employeeWithEmailCalled && idtype === "employeeWithEmail")
              callEmployeeWithEmailQuery({ variables: {} });
            if (idtype === "vendor")
              return (
                <Form.Item
                  name="id"
                  label={t("reportcenter.labels.vendor")}
                  rules={[
                    {
                      required: true
                      //message: t("general.validation.required"),
                    }
                  ]}
                >
                  <VendorSearchSelect options={vendorData ? vendorData.vendors : []} />
                </Form.Item>
              );
            if (idtype === "employee")
              return (
                <Form.Item
                  name="id"
                  label={t("reportcenter.labels.employee")}
                  rules={[
                    {
                      required: true
                      //message: t("general.validation.required"),
                    }
                  ]}
                >
                  <EmployeeSearchSelect options={employeeData ? employeeData.employees : []} />
                </Form.Item>
              );
            //This was introduced with tasks before assigned_to was shifted to UUID. Keeping in place for reference in the future if needed.
            if (idtype === "employeeWithEmail")
              return (
                <Form.Item
                  name="id"
                  label={t("reportcenter.labels.employee")}
                  rules={[
                    {
                      required: true
                      //message: t("general.validation.required"),
                    }
                  ]}
                >
                  <EmployeeSearchSelectEmail options={employeeWithEmailData ? employeeWithEmailData.employees : []} />
                </Form.Item>
              );
            else return null;
          }}
        </Form.Item>
        <Form.Item style={{ margin: 0, padding: 0 }} dependencies={["key"]}>
          {() => {
            const key = form.getFieldValue("key");
            const datedisable = Templates[key] && Templates[key].datedisable;
            if (datedisable !== true) {
              return (
                <Form.Item
                  name="dates"
                  label={t("reportcenter.labels.dates")}
                  rules={[
                    {
                      required: true
                      //message: t("general.validation.required"),
                    },
                    {
                      validator: (_, value) => {
                        if (value && value[0] && value[1]) {
                          const relatedRestrictedReport = restrictedReports.find((r) => r.key === key);
                          if (relatedRestrictedReport) {
                            const diffInDays = (value[1] - value[0]) / (1000 * 3600 * 24);
                            if (diffInDays > relatedRestrictedReport.days) {
                              return Promise.reject(t("general.validation.dateRangeExceeded"));
                            }
                          }
                        }
                        return Promise.resolve();
                      }
                    }
                  ]}
                >
                  <DatePicker.RangePicker format="MM/DD/YYYY" presets={DatePickerRanges} />
                </Form.Item>
              );
            } else return null;
          }}
        </Form.Item>
        <Form.Item style={{ margin: 0, padding: 0 }} dependencies={["key"]}>
          {() => {
            const key = form.getFieldValue("key");
            //Kind of Id
            const reporttype = Templates[key] && Templates[key].reporttype;

            if (reporttype === "excel")
              return (
                <Form.Item label={t("general.labels.sendby")} name="sendbyexcel" initialValue="excel">
                  <Radio.Group>
                    <Radio value="excel">{t("general.labels.excel")}</Radio>
                  </Radio.Group>
                </Form.Item>
              );
            if (reporttype === "text")
              return (
                <Form.Item label={t("general.labels.sendby")} name="sendbytext" initialValue="text">
                  <Radio.Group>
                    <Radio value="text">{t("general.labels.text")}</Radio>
                  </Radio.Group>
                </Form.Item>
              );
            if (reporttype !== "excel" || reporttype !== "text")
              return (
                <Form.Item label={t("general.labels.sendby")} name="sendby" initialValue="print">
                  <Radio.Group>
                    <Radio value="email">{t("general.labels.email")}</Radio>
                    <Radio value="print">{t("general.labels.print")}</Radio>
                  </Radio.Group>
                </Form.Item>
              );
          }}
        </Form.Item>

        <div
          style={{
            display: "flex",
            justifyContent: "center",
            marginTop: "1rem"
          }}
        >
          <Button onClick={() => form.submit()} style={{}} loading={loading}>
            {t("reportcenter.actions.generate")}
          </Button>
        </div>
      </Form>
    </div>
  );
}

const restrictedReports = [
  { key: "job_costing_ro", days: 183 },
  { key: "job_costing_ro_date_summary", days: 183 },
  { key: "job_costing_ro_csr", days: 183 },
  { key: "job_costing_ro_ins_co", days: 183 },
  { key: "job_costing_ro_date_detail", days: 183 },
  { key: "job_costing_ro_estimator", days: 183 },
  { key: "job_lifecycle_date_detail", days: 183 },
  { key: "job_lifecycle_date_summary", days: 183 },
  { key: "customer_list", days: 736 },
  { key: "customer_list_excel", days: 736 }
];
