import {
  CheckCircleFilled,
  CheckCircleOutlined,
  DeleteFilled,
  DeleteOutlined,
  EditFilled,
  PlusCircleFilled,
  SyncOutlined
} from "@ant-design/icons";
import { Button, Card, Space, Switch } from "antd";
import queryString from "query-string";
import { useCallback, useEffect } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { Link, useLocation, useNavigate } from "react-router-dom";
import { setModalContext } from "../../redux/modals/modals.actions";
import { pageLimit } from "../../utils/config";
import { DateFormatter, DateTimeFormatter } from "../../utils/DateFormatter.jsx";
import dayjs from "../../utils/day";
import ShareToTeamsButton from "../share-to-teams/share-to-teams.component.jsx";
import PriorityLabel from "../../utils/tasksPriorityLabel.jsx";
import { logImEXEvent } from "../../firebase/firebase.utils.js";
import ResponsiveTable from "../responsive-table/responsive-table.component";

/**
 * Task List Component
 * @param dueDate
 * @returns {Element}
 * @constructor
 */
const DueDateRecord = ({ dueDate }) => {
  if (!dueDate) return <></>;

  const dueDateDayjs = dayjs(dueDate);
  const relativeDueDate = dueDateDayjs.fromNow();
  const isBeforeToday = dueDateDayjs.isBefore(dayjs());

  return (
    <div title={relativeDueDate} style={isBeforeToday ? { color: "red" } : {}}>
      <DateFormatter>{dueDate}</DateFormatter>
    </div>
  );
};

const RemindAtRecord = ({ remindAt }) => {
  if (!remindAt) return <></>;

  const remindAtDayjs = dayjs(remindAt);
  const relativeRemindAtDate = remindAtDayjs.fromNow();
  const isBeforeToday = remindAtDayjs.isBefore(dayjs());

  return (
    <div title={relativeRemindAtDate} style={isBeforeToday ? { color: "red" } : {}}>
      <DateTimeFormatter>{remindAt}</DateTimeFormatter>
    </div>
  );
};

const mapDispatchToProps = (dispatch) => ({
  // Existing dispatch props...
  setTaskUpsertContext: (context) => dispatch(setModalContext({ context, modal: "taskUpsert" }))
});

const mapStateToProps = () => ({});

export default connect(mapStateToProps, mapDispatchToProps)(TaskListComponent);

function TaskListComponent({
  bodyshop,
  loading,
  tasks,
  total,
  titleTranslation,
  refetch,
  toggleCompletedStatus,
  setTaskUpsertContext,
  toggleDeletedStatus,
  relationshipType,
  relationshipId,
  onlyMine,
  parentJobId,
  query,
  showRo = true
}) {
  const { t } = useTranslation();
  const location = useLocation();

  const search = queryString.parse(useLocation().search);

  // Extract Query Params
  const { page, sortcolumn, sortorder, deleted, completed, mine } = search;

  const history = useNavigate();
  const columns = [];

  useEffect(() => {
    // This is a hack to force the page to change if the query params change (partssublet for example)
  }, [location]);

  columns.push({
    title: t("tasks.fields.created_at"),
    dataIndex: "created_at",
    key: "created_at",
    width: "10%",
    defaultSortOrder: "descend",
    sorter: true,
    sortOrder: sortcolumn === "created_at" && sortorder,
    render: (text, record) => <DateTimeFormatter>{record.created_at}</DateTimeFormatter>
  });

  columns.push({
    title: t("tasks.fields.created_by"),
    dataIndex: "created_by",
    key: "created_by",
    width: "8%",
    defaultSortOrder: "descend",
    sorter: true,
    sortOrder: sortcolumn === "created_by" && sortorder,
    render: (text, record) => record.created_by
  });

  if (!onlyMine) {
    columns.push({
      title: t("tasks.fields.assigned_to"),
      dataIndex: "assigned_to",
      key: "assigned_to",
      width: "8%",
      sorter: true,
      sortOrder: sortcolumn === "assigned_to" && sortorder,
      render: (text, record) => {
        const employee = bodyshop?.employees?.find((e) => e.id === record.assigned_to);
        return employee ? `${employee.first_name} ${employee.last_name}` : t("general.labels.na");
      }
    });
  }

  columns.push({
    title: t("tasks.fields.related_items"),
    key: "related_items",
    width: "12%",
    render: (text, record) => {
      const items = [];

      // Job
      if (showRo && record.job) {
        items.push(
          <Link key="job" to={`/manage/jobs/${record.job.id}?tab=tasks`}>
            {t("tasks.fields.job.ro_number")}: {record.job.ro_number}
          </Link>
        );
      }
      if (showRo && !record.job) {
        items.push(`${t("tasks.fields.job.ro_number")}: ${t("general.labels.na")}`);
      }

      // Jobline
      if (record.jobline?.line_desc) {
        items.push(
          <span key="jobline">
            {t("tasks.fields.jobline")}: {record.jobline.line_desc}
          </span>
        );
      }

      // Parts Order
      if (record.parts_order) {
        const { order_number, vendor } = record.parts_order;
        const partsOrderText =
          order_number && vendor?.name ? `${order_number} - ${vendor.name}` : t("general.labels.na");
        items.push(
          <Link
            key="parts_order"
            to={`/manage/jobs/${record.job.id}?partsorderid=${record.parts_order.id}&tab=partssublet`}
          >
            {t("tasks.fields.parts_order")}: {partsOrderText}
          </Link>
        );
      }

      // Bill
      if (record.bill) {
        const { invoice_number, vendor } = record.bill;
        const billText = invoice_number && vendor?.name ? `${invoice_number} - ${vendor.name}` : t("general.labels.na");
        items.push(
          <Link key="bill" to={`/manage/jobs/${record.job.id}?billid=${record.bill.id}&tab=partssublet`}>
            {t("tasks.fields.bill")}: {billText}
          </Link>
        );
      }

      return items.length > 0 ? <Space orientation="vertical">{items}</Space> : null;
    }
  });

  columns.push(
    {
      title: t("tasks.fields.title"),
      dataIndex: "title",
      key: "title",
      minWidth: "20%",
      sorter: true,
      sortOrder: sortcolumn === "title" && sortorder
    },
    {
      title: t("tasks.fields.due_date"),
      dataIndex: "due_date",
      key: "due_date",
      sorter: true,
      sortOrder: sortcolumn === "due_date" && sortorder,
      width: "8%",
      render: (text, record) => <DueDateRecord dueDate={record.due_date} />
    },
    {
      title: t("tasks.fields.remind_at"),
      dataIndex: "remind_at",
      key: "remind_at",
      sorter: true,
      sortOrder: sortcolumn === "remind_at" && sortorder,
      width: "10%",
      render: (text, record) => <RemindAtRecord remindAt={record.remind_at} />
    },
    {
      title: t("tasks.fields.priority"),
      dataIndex: "priority",
      key: "priority",
      sorter: true,
      sortOrder: sortcolumn === "priority" && sortorder,
      width: "8%",
      render: (text, record) => <PriorityLabel priority={record.priority} />
    },
    {
      title: t("tasks.fields.actions"),
      key: "toggleCompleted",
      width: 260,
      render: (text, record) => (
        <Space orientation="horizontal" size="small" style={{ maxWidth: "100%", whiteSpace: "nowrap" }}>
          <ShareToTeamsButton
            linkText=""
            urlOverride={`${window.location.origin}/manage/tasks/alltasks?taskid=${record.id}`}
          />
          <Button
            title={t("tasks.buttons.edit")}
            icon={<EditFilled />}
            onClick={() => {
              setTaskUpsertContext({
                context: {
                  existingTask: record,
                  query
                }
              });
            }}
          />
          <Button
            title={t("tasks.buttons.complete")}
            onClick={() => toggleCompletedStatus(record.id, record.completed)}
            icon={record.completed ? <CheckCircleOutlined /> : <CheckCircleFilled />}
          />

          <Button
            title={t("tasks.buttons.delete")}
            onClick={() => toggleDeletedStatus(record.id, record.deleted)}
            icon={record.deleted ? <DeleteOutlined /> : <DeleteFilled />}
          />
        </Space>
      )
    }
  );

  const handleCreateTask = useCallback(() => {
    setTaskUpsertContext({
      actions: {},
      context: {
        jobid: parentJobId,
        [relationshipType]: relationshipId,
        query
      }
    });
  }, [parentJobId, relationshipId, relationshipType, setTaskUpsertContext, query]);

  const handleTableChange = (pagination, filters, sorter) => {
    search.page = pagination.current;
    search.sortcolumn = sorter.columnKey;
    search.sortorder = sorter.order;
    history({ search: queryString.stringify(search) });
  };

  const handleSwitchChange = useCallback(
    (param, value) => {
      if (value) {
        search[param] = "true";
      } else {
        delete search[param];
      }
      logImEXEvent("tasks_filter", { key: param });
      history({ search: queryString.stringify(search) });
    },
    [history, search]
  );

  const expandableRow = (record) => {
    return (
      <Card title={t("tasks.fields.description")} size="small">
        {record.description}
      </Card>
    );
  };

  /**
   * Extra actions for the tasks
   * @type {Function}
   */
  const tasksExtra = useCallback(() => {
    return (
      <Space orientation="horizontal">
        {!onlyMine && (
          <Switch
            checkedChildren={t("tasks.buttons.myTasks")}
            unCheckedChildren={t("tasks.buttons.allTasks")}
            title={t("tasks.titles.mine")}
            checked={mine === "true"}
            onChange={(value) => handleSwitchChange("mine", value)}
          />
        )}
        <Switch
          checkedChildren={<CheckCircleFilled />}
          unCheckedChildren={<CheckCircleOutlined />}
          title={t("tasks.titles.completed")}
          checked={completed === "true"}
          onChange={(value) => handleSwitchChange("completed", value)}
        />
        <Switch
          checkedChildren={<DeleteFilled />}
          unCheckedChildren={<DeleteOutlined />}
          title={t("tasks.titles.deleted")}
          checked={deleted === "true"}
          onChange={(value) => handleSwitchChange("deleted", value)}
        />
        <Button title={t("tasks.buttons.refresh")} onClick={() => refetch()} icon={<SyncOutlined />} />

        <Button title={t("tasks.buttons.create")} onClick={handleCreateTask} icon={<PlusCircleFilled />}>
          {t("tasks.buttons.create")}
        </Button>
      </Space>
    );
  }, [refetch, deleted, completed, mine, onlyMine, t, handleSwitchChange, handleCreateTask]);

  return (
    <Card title={titleTranslation} extra={tasksExtra()}>
      <ResponsiveTable
        loading={loading}
        pagination={{
          pageSize: pageLimit,
          current: parseInt(page || 1),
          total: total,
          responsive: true,
          showQuickJumper: true
        }}
        columns={columns}
        mobileColumnKeys={["title", "due_date", "priority", "toggleCompleted"]}
        rowKey="id"
        dataSource={tasks}
        onChange={handleTableChange}
        expandable={{
          expandedRowRender: expandableRow,
          rowExpandable: (record) => record.description
        }}
      />
    </Card>
  );
}
