import { SyncOutlined } from "@ant-design/icons";
import { PageHeader } from "@ant-design/pro-layout";
import { useSplitTreatments } from "@splitsoftware/splitio-react";
import { Button, Dropdown, Input, Space, Statistic, Table } from "antd";
import _ from "lodash";
import { useEffect, useMemo, useRef, useState } from "react";
import ReactDragListView from "react-drag-listview";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectTechnician } from "../../redux/tech/tech.selectors";
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
import Prompt from "../../utils/prompt.js";
import AlertComponent from "../alert/alert.component.jsx";
import ProductionListColumnsAdd from "../production-list-columns/production-list-columns.add.component";
import ProductionListColumns from "../production-list-columns/production-list-columns.data";
import ProductionListDetail from "../production-list-detail/production-list-detail.component";
import { ProductionListConfigManager } from "./production-list-config-manager.component.jsx";
import ProductionListPrint from "./production-list-print.component";
import ResizeableTitle from "./production-list-table.resizeable.component";

const mapStateToProps = createStructuredSelector({
  bodyshop: selectBodyshop,
  technician: selectTechnician,
  currentUser: selectCurrentUser
});

export function ProductionListTable({ loading, data, refetch, bodyshop, technician, currentUser }) {
  const [searchText, setSearchText] = useState("");
  const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
  const {
    treatments: { Production_List_Status_Colors, Enhanced_Payroll }
  } = useSplitTreatments({
    attributes: {},
    names: ["Production_List_Status_Colors", "Enhanced_Payroll"],
    splitKey: bodyshop.imexshopid
  });
  const assoc = bodyshop.associations.find((a) => a.useremail === currentUser.email);
  const defaultView = assoc?.default_prod_list_view;
  const initialStateRef = useRef(
    (bodyshop.production_config &&
      bodyshop.production_config.find((p) => p.name === defaultView)?.columns.tableState) ||
      (bodyshop.production_config && bodyshop.production_config[0]?.columns.tableState) || {
        sortedInfo: {},
        filteredInfo: { text: "" }
      }
  );
  const initialColumnsRef = useRef(
    (initialStateRef.current &&
      bodyshop?.production_config
        ?.find((p) => p.name === defaultView)
        ?.columns.columnKeys.map((k) => {
          return {
            ...ProductionListColumns({
              bodyshop,
              refetch,
              technician,
              state: initialStateRef.current,
              data,
              activeStatuses: bodyshop.md_ro_statuses.active_statuses,
              treatments: { Production_List_Status_Colors, Enhanced_Payroll }
            }).find((e) => e.key === k.key),
            width: k.width ?? 100
          };
        })) ||
      []
  );
  const [state, setState] = useState(initialStateRef.current);
  const [columns, setColumns] = useState(initialColumnsRef.current);
  const { t } = useTranslation();
  const matchingColumnConfig = useMemo(() => {
    return bodyshop?.production_config?.find((p) => p.name === defaultView);
  }, [bodyshop.production_config, defaultView]);

  useEffect(() => {
    const newColumns =
      matchingColumnConfig?.columns.columnKeys.map((k) => {
        return {
          ...ProductionListColumns({
            bodyshop,
            technician,
            refetch,
            state,
            data: data,
            activeStatuses: bodyshop.md_ro_statuses.active_statuses,
            treatments: { Production_List_Status_Colors, Enhanced_Payroll }
          }).find((e) => e.key === k.key),
          width: k.width ?? 100
        };
      }) || [];
    // Only update columns if they haven't been manually changed by the user
    if (_.isEqual(initialColumnsRef.current, columns)) {
      setColumns(newColumns);
    }
  }, [
    matchingColumnConfig,
    bodyshop,
    technician,
    data,
    Enhanced_Payroll,
    Production_List_Status_Colors,
    refetch,
    state,
    columns
  ]);

  const handleTableChange = (pagination, filters, sorter) => {
    const newState = {
      ...state,
      filteredInfo: filters,
      sortedInfo: { columnKey: sorter.columnKey, order: sorter.order }
    };
    if (!_.isEqual(newState, state)) {
      setState(newState);
      setHasUnsavedChanges(true);
    }
  };

  const onDragEnd = (fromIndex, toIndex) => {
    if (fromIndex === toIndex) return;
    const columnsCopy = [...columns];
    const [movedItem] = columnsCopy.splice(fromIndex, 1);
    columnsCopy.splice(toIndex, 0, movedItem);
    if (!_.isEqual(columnsCopy, columns)) {
      setColumns(columnsCopy);
      setHasUnsavedChanges(true);
    }
  };

  const removeColumn = (e) => {
    const { key } = e;
    const newColumns = columns.filter((i) => i.key !== key);
    if (!_.isEqual(newColumns, columns)) {
      setColumns(newColumns);
      setHasUnsavedChanges(true);
    }
  };

  const handleResize =
    (index) =>
    (e, { size }) => {
      const nextColumns = [...columns];
      nextColumns[index] = {
        ...nextColumns[index],
        width: size.width
      };
      if (!_.isEqual(nextColumns, columns)) {
        setColumns(nextColumns);
        setHasUnsavedChanges(true);
      }
    };

  const addColumn = (newColumn) => {
    const updatedColumns = [...columns, newColumn];
    if (!_.isEqual(updatedColumns, columns)) {
      setColumns(updatedColumns);
      setHasUnsavedChanges(true);
    }
  };

  const headerItem = (col) => {
    const menu = {
      onClick: removeColumn,
      items: [
        {
          key: col.key,
          label: t("production.actions.removecolumn")
        }
      ]
    };
    return (
      <Dropdown className="prod-header-dropdown" menu={menu} trigger={["contextMenu"]}>
        <span>{col.title}</span>
      </Dropdown>
    );
  };

  const resetChanges = () => {
    setState(initialStateRef.current);
    setColumns(initialColumnsRef.current);
    setHasUnsavedChanges(false);
  };

  const filterData = (item, searchText) => {
    const fieldsToSearch = [
      item.ro_number,
      item.ownr_co_nm,
      item.ownr_fn,
      item.ownr_ln,
      item.status,
      item.ins_co_nm,
      item.clm_no,
      item.v_model_desc,
      item.v_make_desc
    ];
    return fieldsToSearch.some((field) => (field || "").toString().toLowerCase().includes(searchText.toLowerCase()));
  };

  const dataSource = searchText === "" ? data : data.filter((j) => filterData(j, searchText));

  if (!columns) return <div>No columns found.</div>;

  const totalHrs = data
    .reduce(
      (acc, val) => acc + (val.labhrs?.aggregate?.sum?.mod_lb_hrs || 0) + (val.larhrs?.aggregate?.sum?.mod_lb_hrs || 0),
      0
    )
    .toFixed(1);
  const totalLAB = data.reduce((acc, val) => acc + (val.labhrs?.aggregate?.sum?.mod_lb_hrs || 0), 0).toFixed(1);
  const totalLAR = data.reduce((acc, val) => acc + (val.larhrs?.aggregate?.sum?.mod_lb_hrs || 0), 0).toFixed(1);

  return (
    <div>
      <Prompt when={hasUnsavedChanges} beforeUnload={true} message={t("general.messages.unsavedchangespopup")} />
      {hasUnsavedChanges && (
        <AlertComponent
          type="warning"
          message={
            <div>
              <span>{t("general.messages.unsavedchanges")} </span>
              <span
                onClick={resetChanges}
                style={{
                  cursor: "pointer",
                  textDecoration: "underline",
                  color: "var(--reset-link-color)"
                }}
              >
                {t("general.actions.reset")}
              </span>
            </div>
          }
        />
      )}
      <PageHeader
        title={
          <Space>
            <Statistic title={t("dashboard.titles.productionhours")} value={totalHrs} />
            <Statistic title={t("dashboard.titles.labhours")} value={totalLAB} />
            <Statistic title={t("dashboard.titles.larhours")} value={totalLAR} />
            <Statistic title={t("appointments.labels.inproduction")} value={dataSource?.length} />
          </Space>
        }
        extra={
          <Space wrap>
            <Button
              onClick={() => {
                refetch && refetch();
              }}
            >
              <SyncOutlined />
            </Button>
            <ProductionListColumnsAdd
              columnState={[columns, setColumns]}
              tableState={state}
              data={data}
              onColumnAdd={addColumn}
            />
            <ProductionListConfigManager
              columns={columns}
              setColumns={setColumns}
              state={state}
              setState={setState}
              refetch={refetch}
              data={data}
              bodyshop={bodyshop}
              technician={technician}
              currentUser={currentUser}
              setHasUnsavedChanges={setHasUnsavedChanges}
              hasUnsavedChanges={hasUnsavedChanges}
              onSave={() => {
                setHasUnsavedChanges(false);
                initialStateRef.current = state;
              }}
            />
            <Input
              onChange={(e) => setSearchText(e.target.value)}
              placeholder={t("general.labels.search")}
              value={searchText}
            />
            <ProductionListPrint />
          </Space>
        }
      />
      <ProductionListDetail jobs={dataSource} />
      <ReactDragListView.DragColumn onDragEnd={onDragEnd} nodeSelector="th" handleSelector=".prod-header-dropdown">
        <Table
          sticky
          pagination={false}
          size="small"
          {...(Production_List_Status_Colors.treatment === "on" && {
            onRow: (record, index) => {
              if (!bodyshop.md_ro_statuses.production_colors) return null;
              const color = bodyshop.md_ro_statuses.production_colors.find((x) => x.status === record.status);
              if (!color) {
                if (index % 2 === 0)
                  return {
                    style: {
                      backgroundColor: "var(--table-row-even-bg)"
                    }
                  };
                return null;
              }
              return {
                className: "rowWithColor",
                style: {
                  "--bgColor": color.color
                    ? `rgba(${color.color.r},${color.color.g},${color.color.b},${color.color.a || 1})`
                    : "var(--status-row-bg-fallback)"
                }
              };
            }
          })}
          components={{
            header: {
              cell: ResizeableTitle
            }
          }}
          columns={columns.map((c, index) => {
            return {
              ...c,
              filteredValue: state.filteredInfo[c.key] || null,
              sortOrder: state.sortedInfo.columnKey === c.key && state.sortedInfo.order,
              title: headerItem(c),
              ellipsis: true,
              width: c.width ?? 100,
              onHeaderCell: (column) => ({
                width: column.width,
                onResize: handleResize(index)
              })
            };
          })}
          rowKey="id"
          loading={loading}
          dataSource={dataSource}
          scroll={{ x: 1000 }}
          onChange={handleTableChange}
        />
      </ReactDragListView.DragColumn>
    </div>
  );
}

export default connect(mapStateToProps, null)(ProductionListTable);
