import { CloseOutlined, DeleteFilled } from "@ant-design/icons";
import { closestCenter, DndContext, PointerSensor, useSensor, useSensors } from "@dnd-kit/core";
import { arrayMove, rectSortingStrategy, SortableContext, useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { Button, Form, Select, Space } from "antd";
import { ChromePicker } from "react-color";
import { useTranslation } from "react-i18next";
import styled from "styled-components";
import { getFormListItemTitle } from "../form-list-move-arrows/form-list-item-title.utils";
import ConfigListEmptyState from "../layout-form-row/config-list-empty-state.component.jsx";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import { DEFAULT_TRANSLUCENT_CARD_COLOR, getTintedCardSurfaceStyles } from "./shop-info.color.utils";

import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { useTreatmentsWithConfig } from "@splitsoftware/splitio-react";

const mapStateToProps = createStructuredSelector({
  bodyshop: selectBodyshop
});

const mapDispatchToProps = () => ({
  //setUserLanguage: language => dispatch(setUserLanguage(language))
});
export default connect(mapStateToProps, mapDispatchToProps)(ShopInfoROStatusComponent);

const SelectorDiv = styled.div`
  .ant-form-item .ant-select {
    width: 200px;
  }

  .production-status-color-title-select {
    min-width: 160px;
    width: 100%;
  }

  .production-status-color-title-select .ant-select-selector {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    padding-inline: 0 !important;
  }

  .production-status-color-title-select .ant-select-selection-item,
  .production-status-color-title-select .ant-select-selection-placeholder {
    font-weight: 500;
  }

  .job-statuses-source-select .ant-select-selector {
    align-items: flex-start !important;
  }

  .job-statuses-source-select .ant-select-selection-wrap {
    gap: 4px 0;
  }

  .job-statuses-source-tag-wrapper {
    display: inline-flex;
    max-width: 100%;
    margin-inline-end: 4px;
    touch-action: none;
  }

  .job-statuses-source-tag-wrapper .ant-select-selection-item {
    max-width: 100%;
    cursor: grab;
    margin-inline-end: 0;
    user-select: none;
  }

  .job-statuses-source-tag-wrapper .ant-select-selection-item-content {
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .job-statuses-source-tag-wrapper .ant-select-selection-item:active {
    cursor: grabbing;
  }

  .job-statuses-source-tag-wrapper .ant-select-selection-item-remove {
    flex: none;
  }

  .job-statuses-source-tag-wrapper--dragging {
    opacity: 0.55;
  }
`;

const normalizeStatuses = (statuses) => [...new Set((statuses || []).map((item) => item?.trim()).filter(Boolean))];

const DraggableStatusTag = ({ label, value, closable, onClose }) => {
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
    id: value
  });
  const labelText = String(label ?? value);

  return (
    <span
      ref={setNodeRef}
      className={`job-statuses-source-tag-wrapper ${isDragging ? "job-statuses-source-tag-wrapper--dragging" : ""}`}
      style={{ transform: CSS.Transform.toString(transform), transition }}
      onPointerDownCapture={(event) => {
        if (event.target.closest(".ant-tag-close-icon")) {
          event.stopPropagation();
        }
      }}
      {...attributes}
      {...listeners}
    >
      <span
        className="ant-select-selection-item"
        onMouseDown={(event) => {
          if (event.target.closest(".ant-select-selection-item-remove")) {
            event.stopPropagation();
            return;
          }

          event.preventDefault();
        }}
        title={labelText}
      >
        <span className="ant-select-selection-item-content">{labelText}</span>
        {closable ? (
          <span
            className="ant-select-selection-item-remove"
            onClick={(event) => {
              event.stopPropagation();
              onClose?.(event);
            }}
            onMouseDown={(event) => {
              event.stopPropagation();
            }}
          >
            <CloseOutlined />
          </span>
        ) : null}
      </span>
    </span>
  );
};

const SortableStatusesSelect = ({ value, onChange }) => {
  const statuses = normalizeStatuses(value);
  const tagSensors = useSensors(
    useSensor(PointerSensor, {
      activationConstraint: {
        distance: 6
      }
    })
  );

  const handleStatusesChange = (nextValues) => {
    onChange?.(normalizeStatuses(nextValues));
  };

  const handleStatusSortEnd = ({ active, over }) => {
    if (!over || active.id === over.id) return;

    const oldIndex = statuses.indexOf(active.id);
    const newIndex = statuses.indexOf(over.id);

    if (oldIndex < 0 || newIndex < 0) return;

    onChange?.(arrayMove(statuses, oldIndex, newIndex));
  };

  const renderStatusTag = ({ label, value: tagValue, closable, onClose }) => {
    return <DraggableStatusTag closable={closable} label={label} onClose={onClose} value={tagValue} />;
  };

  return (
    <DndContext collisionDetection={closestCenter} onDragEnd={handleStatusSortEnd} sensors={tagSensors}>
      <SortableContext items={statuses} strategy={rectSortingStrategy}>
        <Select
          className="job-statuses-source-select"
          mode="tags"
          onChange={handleStatusesChange}
          tagRender={renderStatusTag}
          value={statuses}
        />
      </SortableContext>
    </DndContext>
  );
};

export function ShopInfoROStatusComponent({ bodyshop, form }) {
  const { t } = useTranslation();
  const allStatuses = normalizeStatuses(Form.useWatch(["md_ro_statuses", "statuses"], form));
  const productionStatuses = Form.useWatch(["md_ro_statuses", "production_statuses"], form) || [];
  const additionalBoardStatuses = Form.useWatch(["md_ro_statuses", "additional_board_statuses"], form) || [];
  const productionColors = Form.useWatch(["md_ro_statuses", "production_colors"], form) || [];
  const statusOptions = allStatuses;
  const statusSelectOptions = statusOptions.map((item) => ({ value: item, label: item }));
  const availableProductionStatuses = [...new Set([...productionStatuses, ...additionalBoardStatuses].filter(Boolean))];

  const {
    treatments: { Production_List_Status_Colors }
  } = useTreatmentsWithConfig({
    attributes: {},
    names: ["Production_List_Status_Colors"],
    splitKey: bodyshop.imexshopid
  });

  return (
    <SelectorDiv id="jobstatus">
      <LayoutFormRow grow header={t("bodyshop.labels.job_status_options")}>
        <div>
          <Form.Item
            name={["md_ro_statuses", "statuses"]}
            label={t("bodyshop.labels.alljobstatuses")}
            rules={[
              {
                validator: async (_, value) => {
                  const populatedStatuses = normalizeStatuses(value);

                  if (populatedStatuses.length === 0) {
                    return Promise.reject(new Error(t("general.validation.required")));
                  }

                  if (populatedStatuses.length !== (value || []).filter(Boolean).length) {
                    return Promise.reject(new Error(t("bodyshop.errors.duplicate_job_status")));
                  }
                }
              }
            ]}
          >
            <SortableStatusesSelect />
          </Form.Item>
          <Form.Item
            name={["md_ro_statuses", "active_statuses"]}
            label={t("bodyshop.fields.statuses.active_statuses")}
            rules={[
              {
                required: true,
                //message: t("general.validation.required"),
                type: "array"
              }
            ]}
          >
            <Select mode="multiple" options={statusSelectOptions} />
          </Form.Item>
          <Form.Item
            name={["md_ro_statuses", "pre_production_statuses"]}
            label={t("bodyshop.fields.statuses.pre_production_statuses")}
            rules={[
              {
                required: true,
                //message: t("general.validation.required"),
                type: "array"
              }
            ]}
          >
            <Select mode="multiple" options={statusSelectOptions} />
          </Form.Item>
          <Form.Item
            name={["md_ro_statuses", "production_statuses"]}
            label={t("bodyshop.fields.statuses.production_statuses")}
            rules={[
              {
                required: true,
                //message: t("general.validation.required"),
                type: "array"
              }
            ]}
          >
            <Select mode="multiple" options={statusSelectOptions} />
          </Form.Item>
          <Form.Item
            name={["md_ro_statuses", "post_production_statuses"]}
            label={t("bodyshop.fields.statuses.post_production_statuses")}
            rules={[
              {
                required: true,
                //message: t("general.validation.required"),
                type: "array"
              }
            ]}
          >
            <Select mode="multiple" options={statusSelectOptions} />
          </Form.Item>
          <Form.Item
            name={["md_ro_statuses", "ready_statuses"]}
            label={t("bodyshop.fields.statuses.ready_statuses")}
            rules={[
              {
                //required: true,
                //message: t("general.validation.required"),
                type: "array"
              }
            ]}
          >
            <Select mode="multiple" options={statusSelectOptions} />
          </Form.Item>
          <Form.Item
            name={["md_ro_statuses", "additional_board_statuses"]}
            label={t("bodyshop.fields.statuses.additional_board_statuses")}
            rules={[
              {
                //required: true,
                //message: t("general.validation.required"),
                type: "array"
              }
            ]}
          >
            <Select mode="multiple" options={statusSelectOptions} />
          </Form.Item>
        </div>
      </LayoutFormRow>
      <LayoutFormRow grow header={t("general.actions.defaults")}>
        <Form.Item
          label={t("bodyshop.fields.statuses.default_scheduled")}
          rules={[
            {
              required: true
              //message: t("general.validation.required"),
            }
          ]}
          name={["md_ro_statuses", "default_scheduled"]}
        >
          <Select options={statusSelectOptions} />
        </Form.Item>
        <Form.Item
          label={t("bodyshop.fields.statuses.default_arrived")}
          rules={[
            {
              required: true
              //message: t("general.validation.required"),
            }
          ]}
          name={["md_ro_statuses", "default_arrived"]}
        >
          <Select options={statusSelectOptions} />
        </Form.Item>
        <Form.Item
          label={t("bodyshop.fields.statuses.default_exported")}
          rules={[
            {
              required: true
              //message: t("general.validation.required"),
            }
          ]}
          name={["md_ro_statuses", "default_exported"]}
        >
          <Select options={statusSelectOptions} />
        </Form.Item>
        <Form.Item
          label={t("bodyshop.fields.statuses.default_imported")}
          rules={[
            {
              required: true
              //message: t("general.validation.required"),
            }
          ]}
          name={["md_ro_statuses", "default_imported"]}
        >
          <Select options={statusSelectOptions} />
        </Form.Item>
        <Form.Item
          label={t("bodyshop.fields.statuses.default_invoiced")}
          rules={[
            {
              required: true
              //message: t("general.validation.required"),
            }
          ]}
          name={["md_ro_statuses", "default_invoiced"]}
        >
          <Select options={statusSelectOptions} />
        </Form.Item>
        <Form.Item
          label={t("bodyshop.fields.statuses.default_completed")}
          rules={[
            {
              required: true
              //message: t("general.validation.required"),
            }
          ]}
          name={["md_ro_statuses", "default_completed"]}
        >
          <Select options={statusSelectOptions} />
        </Form.Item>
        <Form.Item
          label={t("bodyshop.fields.statuses.default_delivered")}
          rules={[
            {
              required: true
              //message: t("general.validation.required"),
            }
          ]}
          name={["md_ro_statuses", "default_delivered"]}
        >
          <Select options={statusSelectOptions} />
        </Form.Item>
        <Form.Item
          label={t("bodyshop.fields.statuses.default_void")}
          rules={[
            {
              required: true
              //message: t("general.validation.required"),
            }
          ]}
          name={["md_ro_statuses", "default_void"]}
        >
          <Select options={statusSelectOptions} />
        </Form.Item>
      </LayoutFormRow>
      {Production_List_Status_Colors.treatment === "on" && (
        <Form.List name={["md_ro_statuses", "production_colors"]}>
          {(fields, { add, remove }) => {
            return (
              <LayoutFormRow
                grow
                header={t("bodyshop.fields.statuses.production_colors")}
                id="production_colors"
                actions={[
                  <Button
                    key="add-production-status-color"
                    type="primary"
                    block
                    onClick={() => {
                      add({
                        color: { ...DEFAULT_TRANSLUCENT_CARD_COLOR }
                      });
                    }}
                  >
                    {t("bodyshop.actions.add_production_status_color")}
                  </Button>
                ]}
              >
                <div>
                  {fields.length === 0 ? (
                    <ConfigListEmptyState actionLabel={t("bodyshop.actions.add_production_status_color")} />
                  ) : (
                    <Space size="large" wrap align="start">
                      {fields.map((field, index) => {
                        const productionColor = productionColors[field.name] || {};
                        const productionColorSurfaceStyles = getTintedCardSurfaceStyles(productionColor.color);
                        const selectedProductionColorStatuses = productionColors
                          .map((item) => item?.status)
                          .filter(Boolean);
                        const productionColorStatusOptions = [
                          ...new Set([productionColor.status, ...availableProductionStatuses])
                        ]
                          .filter(Boolean)
                          .filter(
                            (status) =>
                              status === productionColor.status || !selectedProductionColorStatuses.includes(status)
                          );

                        return (
                          <LayoutFormRow
                            key={field.key}
                            noDivider
                            title={
                              <Form.Item
                                noStyle
                                key={`${index}status`}
                                name={[field.name, "status"]}
                                rules={[
                                  {
                                    required: true
                                    //message: t("general.validation.required"),
                                  }
                                ]}
                              >
                                <Select
                                  className="production-status-color-title-select"
                                  variant="borderless"
                                  placeholder={getFormListItemTitle(
                                    t("jobs.fields.status"),
                                    index,
                                    productionColor.status
                                  )}
                                  options={productionColorStatusOptions.map((item) => ({
                                    value: item,
                                    label: item
                                  }))}
                                />
                              </Form.Item>
                            }
                            extra={
                              <Button
                                type="text"
                                danger
                                icon={<DeleteFilled />}
                                onClick={() => {
                                  remove(field.name);
                                }}
                              />
                            }
                            {...productionColorSurfaceStyles}
                            style={{ width: 260, marginBottom: 0 }}
                          >
                            <div>
                              <Form.Item
                                key={`${index}color`}
                                name={[field.name, "color"]}
                                rules={[
                                  {
                                    required: true
                                    //message: t("general.validation.required"),
                                  }
                                ]}
                              >
                                <ColorPicker />
                              </Form.Item>
                            </div>
                          </LayoutFormRow>
                        );
                      })}
                    </Space>
                  )}
                </div>
              </LayoutFormRow>
            );
          }}
        </Form.List>
      )}
    </SelectorDiv>
  );
}

export const ColorPicker = ({ value, onChange, ...restProps }) => {
  const handleChange = (color) => {
    if (onChange) onChange(color.rgb);
  };
  return <ChromePicker {...restProps} color={value} onChangeComplete={handleChange} />;
};
