import { Layer } from "react-map-gl";
import {
  matchInitialPointLayer,
  unmatchInitialPointLayer,
} from "./layers-config";
import { useLayersVisibility } from "../../stores/useLayersVisibility";
import { useFilters } from "../../stores/useFilters";
import { usePointSelection } from "../../stores/usePointSelection";
import { STATUSES } from "../../config";
import { useRegionFilterExpression } from "./useRegionFilterExpression";
import { LAYER_IDS } from "./constants";

const statusExpression = ["==", ["get", "status"], STATUSES.initial];

const useFilterExpression = () => {
  const { filters } = useFilters();
  const { prediction, categories, region } = filters;
  const { selection } = usePointSelection();
  const includedArr = [...selection.included];
  const excludedArr = [...selection.excluded];

  const regionExpression = useRegionFilterExpression();

  const includedExpression = [
    "in",
    ["get", "location_id"],
    ["literal", includedArr],
  ];
  const excludedExpression = [
    "in",
    ["get", "location_id"],
    ["literal", excludedArr],
  ];
  const predictionExpression = [
    [">=", ["get", "prediction_current"], prediction[0]],
    ["<=", ["get", "prediction_current"], prediction[1]],
  ];

  const categoryExpression =
    categories.length > 0
      ? ["in", ["get", "category"], ["literal", categories]]
      : true;

  const matchFilterExpression = [
    "all",
    statusExpression,
    ["!", excludedExpression],
    [
      "any",
      region
        ? ["all", ...predictionExpression, categoryExpression, regionExpression]
        : ["all", ...predictionExpression, categoryExpression],
      includedExpression,
    ],
  ];

  const unmatchFilterExpression = [
    "all",
    statusExpression,
    ["!", includedExpression],
    [
      "any",
      [
        "!",
        region
          ? [
              "all",
              ...predictionExpression,
              categoryExpression,
              regionExpression,
            ]
          : ["all", ...predictionExpression, categoryExpression],
      ],
      excludedExpression,
    ],
  ];

  return { match: matchFilterExpression, unmatch: unmatchFilterExpression };
};

export const InitialPoints = () => {
  const { isVisible } = useLayersVisibility();
  const { match: matchFilterExpression, unmatch: unmatchFilterExpression } =
    useFilterExpression();

  return (
    <>
      <Layer
        {...matchInitialPointLayer}
        id={LAYER_IDS["initial-unmatch"]}
        source={"points"}
        source-layer={"public.service_placementpoint"}
        layout={{
          ...matchInitialPointLayer.layout,
          visibility: isVisible[LAYER_IDS.initial] ? "visible" : "none",
        }}
        filter={unmatchFilterExpression}
        paint={unmatchInitialPointLayer.paint}
      />
      <Layer
        {...matchInitialPointLayer}
        id={LAYER_IDS["initial-match"]}
        source={"points"}
        source-layer={"public.service_placementpoint"}
        layout={{
          ...matchInitialPointLayer.layout,
          visibility: isVisible[LAYER_IDS.initial] ? "visible" : "none",
        }}
        filter={matchFilterExpression}
        paint={matchInitialPointLayer.paint}
      />
    </>
  );
};
