import { createStore as s } from "zustand";
import { devtools as u } from "zustand/middleware";
import { immer as c } from "zustand/middleware/immer";
import { DYNAMIC_SORT_STORE_ID as m } from "../constants.js";
import { getPurgedInitialSortApplied as v } from "../helpers/getPurgedInitialSortApplyed.js";
const S = (o) => {
  const d = [];
  for (let l = 0; l < o.fields.length; l++) {
    let p;
    const r = o.fields[l];
    p = !0, o.appliedSorts.findIndex(
      (i) => i.field.name === r.name
    ) > -1 && (p = !1), p && d.push(r);
  }
  o.availableFields = d;
}, x = (o) => {
  o.ownerState.isValid = !0;
  for (let d = 0; d < o.appliedSorts.length; d++)
    o.appliedSorts[d].isSet || (o.ownerState.isValid = !1);
}, a = (o) => {
  x(o), S(o), o.ownerState?.isValid && o.automatic && (o.ownerState.isDirty = !1, o.countOnChangeSortsApplyed++);
}, D = (o, d) => {
  const { enabled: l = !1 } = d;
  return l && process.env.NODE_ENV === "development" ? u(o, d) : o;
}, y = (o, d = !1) => {
  const l = {
    countOnChangeSortsApplyed: 0,
    appliedSorts: [],
    availableFields: [],
    // elementRef: null,
    popoverSortData: void 0,
    inputData: "",
    ...o
  };
  let p = null;
  return s(
    D(
      c((r, f) => ({
        ...l,
        actions: {
          /**
           * init es la acción que se ejecuta al inicializar el store
           */
          init: (i) => {
            r((e) => {
              e.appliedSorts = v(
                e.fields,
                i,
                e.actions.getFieldByName
              ), a(e);
            });
          },
          /**
           *  Actualiza la referencia del elemento (inputFilter) desde donde se desprende el listado de campos
           */
          setElementRef: (i) => {
            p = i;
          },
          getElementRef: () => p,
          /**
           * Funcion para obtener un Field a través del nombre
           */
          getFieldByName: (i) => {
            const e = f().fields.find((n) => n.name === i);
            if (e)
              return e;
            throw new Error("Field does not exist");
          },
          /**
           * Elimina un campo sort por su id
           */
          removeSort: (i) => {
            r((e) => {
              const n = e.appliedSorts.findIndex(
                (t) => i === t.id && !t.fixed
              );
              n > -1 && (e.automatic || (e.ownerState.isDirty = !0), e.appliedSorts.splice(n, 1), a(e), e.appliedSorts.length === 0 && (e.ownerState.isDirty = !1));
            });
          },
          /**
           * Elimina un campo sort por el nombre de la columna
           */
          removeExternalSort: (i) => {
            r((e) => {
              const n = e.appliedSorts.findIndex(
                (t) => t.field.name === i && !t.fixed
              );
              n > -1 && (e.appliedSorts.splice(n, 1), a(e), e.appliedSorts.length === 0 && (e.ownerState.isDirty = !1));
            });
          },
          /**
           * showPopoverSortForAdd es la acción que se ejecuta al abrir el popover para agregar un nuevo sort
           */
          showPopoverSortForAdd: (i) => {
            r((e) => {
              e.inputData = "", e.popoverSortData = {
                openFor: "add",
                field: i
              }, e.isOpenPopoverMenuFields = !1, e.ownerState.inEdition = !0;
            });
          },
          /**
           * showPopoverSortForEdit es la acción que se ejecuta al abrir el popover para editar un sort existente
           */
          showPopoverSortForEdit: (i) => {
            r((e) => {
              e.popoverSortData = {
                openFor: "edit",
                sort: i
              };
            }), f().actions.setInEdition(!0);
          },
          /**
           * hidepopoverSort oculta el popover de sort
           */
          hidePopoverSort: (i) => {
            r((e) => {
              e.popoverSortData = void 0;
            }), f().actions.setInEdition(i);
          },
          /**
           * Limpia todos los campos/atributos usados para aplicar un sort
           */
          clearSorts: () => {
            r((i) => {
              i.ownerState.isDirty = !1, i.automatic || (i.ownerState.isDirty = !0), i.appliedSorts = i.appliedSorts.filter((e) => e.fixed), S(i);
            });
          },
          /**
           * Acción que se ejecuta al aplicar los filtros
           */
          fireOnChangeSorts: () => {
            r((i) => {
              i.ownerState?.isValid && (i.ownerState.isDirty = !1, i.countOnChangeSortsApplyed++);
            });
          },
          /**
           * getNewId es la acción que se ejecuta al crear un nuevo sort
           */
          getNewId: () => f().appliedSorts.reduce((i, e) => e.id > i ? e.id : i, 0) + 1,
          /**
           * Agrega un nuevo campo/atributo por el cual se va aplicar el sort
           */
          addSort: (i) => {
            r((e) => {
              e.automatic || (e.ownerState.isDirty = !0), e.appliedSorts.push(i), a(e);
            });
          },
          /**
           * Agrega un nuevo campo/atributo por el cual se va aplicar el sort externo
           */
          addExternalSort: (i) => {
            r((e) => {
              const n = e.appliedSorts.findIndex(
                (t) => t.field.name === i.field.name
              );
              if (n > -1) {
                const t = e.appliedSorts[n];
                e.appliedSorts[n] = {
                  ...i,
                  id: t.id
                };
              } else
                e.automatic || (e.ownerState.isDirty = !0), e.appliedSorts.push(i);
              a(e);
            });
          },
          /**
           * Actualiza un sort existente
           */
          updateSort: (i) => {
            r((e) => {
              const n = e.appliedSorts.findIndex(
                (t) => t.id === i.id
              );
              n > -1 && (e.appliedSorts[n] = i), a(e);
            });
          },
          /**
           * Actualiza el valor del input de busqueda
           */
          setInputData: (i) => {
            r((e) => {
              e.inputData = i;
            });
          },
          /**
           * Actualiza en edicion el estado del componente
           */
          setInEdition: (i) => {
            r((e) => {
              e.ownerState.inEdition = i;
            });
          },
          /**
           * abre el popover para seleccionar los campos a filtrar
           */
          openPopoverMenuFields: () => {
            r((i) => {
              i.isOpenPopoverMenuFields = !0, i.ownerState.inEdition = !0;
            });
          },
          /**
           * cierra el popover para seleccionar los campos a filtrar
           */
          closePopoverMenuFields: (i) => {
            r((e) => {
              e.isOpenPopoverMenuFields = !1, e.ownerState.inEdition = i || !1;
            });
          },
          /**
           * actualiza el tamaño del componente
           */
          setSize: (i) => {
            r((e) => {
              e.size = i, e.ownerState.size = i;
            });
          },
          /**
           * actualiza el visibleRefresh del componente
           */
          setVisibleRefresh: (i) => {
            r((e) => {
              e.visibleRefresh = i;
            });
          }
        }
      })),
      {
        name: `${m}: ${o.storeId}`,
        enabled: d
      }
    )
  );
};
export {
  y as createDynamicSortStore
};
