import type { ReactNode } from "react";
import {
  AlignBottom,
  AlignHorizontally,
  AlignLeft,
  AlignRight,
  AlignTop,
  AlignVertically,
} from "iconsax-react";
import { useEditorStore, type EditorObject } from "../../../store/editorStore";
import type { AlignKind } from "./alignmentUtils";
import {
  deltasForAlign,
  pageBounds,
  unionBoundsOfAlignTargets,
  computeGroupFrameUpdate,
  updatesFromDeltas,
} from "./alignmentUtils";

type AlignmentSettingsProps = {
  pageWidth: number;
  pageHeight: number;
  onUpdate: (id: string, updates: Partial<EditorObject>) => void;
};

type AlignButtonGroupProps = {
  children: ReactNode;
};

type AlignButtonProps = {
  title: string;
  onClick: () => void;
  children: ReactNode;
};

const AlignButtonGroup = ({ children }: AlignButtonGroupProps) => (
  <div className="flex flex-1 overflow-hidden rounded-lg border border-[#E5E5E5] bg-[#F2F2F2] divide-x divide-[#E5E5E5]">
    {children}
  </div>
);

const AlignButton = ({ title, onClick, children }: AlignButtonProps) => (
  <button
    type="button"
    title={title}
    onClick={onClick}
    className="flex flex-1 items-center justify-center py-2.5 text-[#333333] transition-colors hover:bg-black/4 active:bg-black/8"
  >
    {children}
  </button>
);

const alignIconProps = { size: 20, color: "currentColor" as const, variant: "Linear" as const };

const AlignmentSettings = ({
  pageWidth,
  pageHeight,
  onUpdate,
}: AlignmentSettingsProps) => {
  const applyAlign = (kind: AlignKind) => {
    useEditorStore.getState().commitObjectHistoryBeforeChange();
    const { objects: objs, selectedObjectIds: ids, layerRef } = useEditorStore.getState();
    const layer = layerRef?.current ?? null;

    const initial = new Map<string, EditorObject>();
    for (const id of ids) {
      const o = objs.find((x) => x.id === id);
      if (o && o.visible !== false) initial.set(id, { ...o });
    }
    if (initial.size === 0) return;

    const initialList = [...initial.values()];
    const useSelectionBounds = ids.length === 2;
    const target =
      useSelectionBounds && initialList.length === 2
        ? unionBoundsOfAlignTargets(initialList, objs, layer)
        : pageBounds(pageWidth, pageHeight);

    if (!target) return;

    const alignedGroupIds = new Set<string>();

    for (const id of initial.keys()) {
      const obj = initial.get(id)!;
      const { dx, dy } = deltasForAlign(obj, kind, target, objs, layer);
      const updates = updatesFromDeltas(obj, dx, dy);
      if (Object.keys(updates).length === 0) continue;
      onUpdate(id, updates);
      if (obj.type === "group") {
        alignedGroupIds.add(id);
      }
    }

    const { updateObject } = useEditorStore.getState();
    const afterObjects = useEditorStore.getState().objects;
    for (const gid of alignedGroupIds) {
      const patch = computeGroupFrameUpdate(gid, afterObjects, layer);
      if (patch) updateObject(gid, patch);
    }
  };

  return (
    <div className="space-y-3">
      <h4 className="text-[13px] text-[#7A7A7A]">ترازبندی</h4>

      <div className="flex gap-2">
        <AlignButtonGroup>
          <AlignButton title="تراز راست" onClick={() => applyAlign("right")}>
            <AlignRight {...alignIconProps} />
          </AlignButton>
          <AlignButton title="تراز افقی وسط" onClick={() => applyAlign("centerH")}>
            <AlignHorizontally {...alignIconProps} />
          </AlignButton>
          <AlignButton title="تراز چپ" onClick={() => applyAlign("left")}>
            <AlignLeft {...alignIconProps} />
          </AlignButton>
        </AlignButtonGroup>

        <AlignButtonGroup>
          <AlignButton title="تراز بالا" onClick={() => applyAlign("top")}>
            <AlignTop {...alignIconProps} />
          </AlignButton>
          <AlignButton title="تراز عمودی وسط" onClick={() => applyAlign("centerV")}>
            <AlignVertically {...alignIconProps} />
          </AlignButton>
          <AlignButton title="تراز پایین" onClick={() => applyAlign("bottom")}>
            <AlignBottom {...alignIconProps} />
          </AlignButton>
        </AlignButtonGroup>
      </div>
    </div>
  );
};

export default AlignmentSettings;
