import { Button, Card, Space, Switch, Table } from "antd";
import queryString from "query-string";
import React, { useCallback, useEffect } from "react";
import { useTranslation } from "react-i18next";
import { Link, useLocation, useNavigate } from "react-router-dom";
import { pageLimit } from "../../utils/config";
import dayjs from "../../utils/day";
import {
  CheckCircleFilled,
  CheckCircleOutlined,
  DeleteFilled,
  DeleteOutlined,
  EditFilled,
  ExclamationCircleFilled,
  PlusCircleFilled,
  SyncOutlined
} from "@ant-design/icons";
import { DateFormatter, DateTimeFormatter } from "../../utils/DateFormatter.jsx";
import { connect } from "react-redux";
import { setModalContext } from "../../redux/modals/modals.actions";

/**
 * 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>
  );
};

/**
 * Priority Label Component
 * @param priority
 * @returns {Element}
 * @constructor
 */
const PriorityLabel = ({ priority }) => {
  switch (priority) {
    case 1:
      return (
        <div>
          High <ExclamationCircleFilled style={{ marginLeft: "5px", color: "red" }} />
        </div>
      );
    case 2:
      return (
        <div>
          Medium <ExclamationCircleFilled style={{ marginLeft: "5px", color: "yellow" }} />
        </div>
      );
    case 3:
      return (
        <div>
          Low <ExclamationCircleFilled style={{ marginLeft: "5px", color: "green" }} />
        </div>
      );
    default:
      return (
        <div>
          None <ExclamationCircleFilled style={{ marginLeft: "5px" }} />
        </div>
      );
  }
};

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

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

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>
  });

  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");
      }
    });
  }

  if (showRo) {
    columns.push({
      title: t("tasks.fields.job.ro_number"),
      dataIndex: ["job", "ro_number"],
      key: "job.ro_number",
      width: "8%",
      render: (text, record) =>
        record.job ? (
          <Link to={`/manage/jobs/${record.job.id}?tab=tasks`}>{record.job.ro_number || t("general.labels.na")}</Link>
        ) : (
          t("general.labels.na")
        )
    });
  }

  columns.push(
    {
      title: t("tasks.fields.jobline"),
      dataIndex: ["jobline", "id"],
      key: "jobline.id",
      width: "8%",
      render: (text, record) => record?.jobline?.line_desc || ""
    },
    {
      title: t("tasks.fields.parts_order"),
      dataIndex: ["parts_order", "id"],
      key: "part_order.id",
      width: "8%",
      render: (text, record) =>
        record.parts_order ? (
          <Link to={`/manage/jobs/${record.job.id}?partsorderid=${record.parts_order.id}&tab=partssublet`}>
            {record.parts_order.order_number && record.parts_order.vendor && record.parts_order.vendor.name
              ? `${record.parts_order.order_number} - ${record.parts_order.vendor.name}`
              : t("general.labels.na")}
          </Link>
        ) : (
          ""
        )
    },
    {
      title: t("tasks.fields.bill"),
      dataIndex: ["bill", "id"],
      key: "bill.id",
      width: "10%",
      render: (text, record) =>
        record.bill ? (
          <Link to={`/manage/jobs/${record.job.id}?billid=${record.bill.id}&tab=partssublet`}>
            {record.bill.invoice_number && record.bill.vendor && record.bill.vendor.name
              ? `${record.bill.invoice_number} - ${record.bill.vendor.name}`
              : t("general.labels.na")}
          </Link>
        ) : (
          ""
        )
    },
    {
      title: t("tasks.fields.title"),
      dataIndex: "title",
      key: "title",
      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: "5%",
      render: (text, record) => (
        <Space direction="horizontal">
          <Button
            title={t("tasks.buttons.edit")}
            onClick={() => {
              setTaskUpsertContext({
                context: {
                  existingTask: record,
                  query
                }
              });
            }}
          >
            <EditFilled />
          </Button>
          <Button
            title={t("tasks.buttons.complete")}
            onClick={() => toggleCompletedStatus(record.id, record.completed)}
          >
            {record.completed ? <CheckCircleOutlined /> : <CheckCircleFilled />}
          </Button>
          <Button title={t("tasks.buttons.delete")} onClick={() => toggleDeletedStatus(record.id, record.deleted)}>
            {record.deleted ? <DeleteOutlined /> : <DeleteFilled />}
          </Button>
        </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];
      }
      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 direction="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()}>
          <SyncOutlined />
        </Button>
        <Button title={t("tasks.buttons.create")} onClick={handleCreateTask}>
          <PlusCircleFilled />
          {t("tasks.buttons.create")}
        </Button>
      </Space>
    );
  }, [refetch, deleted, completed, mine, onlyMine, t, handleSwitchChange, handleCreateTask]);

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