import { useCallback, useEffect, useRef, useState } from "react";
import { AS } from "@/storageControl";
import { STORAGE_KEYS } from "@/constants";
import { useFavoriteStation } from "@/stateBox/useFavoriteStation";
import { SortGridCard } from "./SortGridCard";
import { CarouselUIMode, StationSource } from "@/types";

type SortModeConfig = {
  listUpStation: any[][];
  setListIndex: (i: number) => void;
  width: number;
  origW: number;
  origH: number;
  cols: number;
  gridPad: number;
  gridGap: number;
  cellW: number;
  cellH: number;
  carouselHeight: number;
  stationSource: StationSource;
};

/** カルーセルの並び替えモードに関わる状態・ロジックをまとめたカスタムフック */
export function useSortMode({
  listUpStation,
  setListIndex,
  width,
  origW,
  origH,
  cols,
  gridPad,
  gridGap,
  cellW,
  cellH,
  carouselHeight,
  stationSource,
}: SortModeConfig) {
  const { setFavoriteStation } = useFavoriteStation();
  // "carousel" | "sort" | "sort-exiting" の 3 値で UI モードを管理
  const [uiMode, setUiMode] = useState<CarouselUIMode>("carousel");
  // ソート開始時のカルーセル位置を保存（setListIndex(-1) される前の値）
  const sortModeStartIndexRef = useRef(0);
  // ソート終了後に移動するインデックス（タップで上書き可、デフォルト 0）
  const exitTargetIndexRef = useRef(0);

  // carousel に戻ったら指定インデックスへ移動
  useEffect(() => {
    if (uiMode === "carousel") {
      setListIndex(exitTargetIndexRef.current);
    }
  }, [uiMode]);

  /** 並び替えモード開始（現在のカルーセル位置を渡す） */
  const startSortMode = useCallback((currentIndex: number) => {
    sortModeStartIndexRef.current = currentIndex;
    exitTargetIndexRef.current = 0; // デフォルトは先頭
    setListIndex(-1); // 未選択状態にして LED を非表示
    setUiMode("sort");
  }, [setListIndex]);

  /** 退場アニメーション完了後にモードを終了 */
  const exitSortMode = useCallback(() => {
    setUiMode("sort-exiting");
    // 退場スプリングが収束するまで待ってから carousel へ
    setTimeout(() => {
      setUiMode("carousel");
    }, listUpStation.length * 40 + 500);
  }, [listUpStation.length]);

  /** Sortable.Grid の renderItem（useCallback でメモ化） */
  const sortGridRenderItem = useCallback(
    ({ item, index }: { item: any; index: number }) => {
      const col = index % cols;
      const row = Math.floor(index / cols);
      const carouselCardCenterX =
        (index - sortModeStartIndexRef.current) * width + width / 2 - gridPad;
      const carouselCardCenterY = carouselHeight / 2;
      const cellCenterX = col * (cellW + gridGap) + cellW / 2;
      const cellCenterY = row * (cellH + gridGap) + cellH / 2;
      const startX = carouselCardCenterX - cellCenterX;
      const startY = carouselCardCenterY - cellCenterY;
      const exitCarouselCardCenterX =
        (index - exitTargetIndexRef.current) * width + width / 2 - gridPad;
      const exitX = exitCarouselCardCenterX - cellCenterX;
      const exitY = carouselCardCenterY - cellCenterY;
      return (
        <SortGridCard
          key={item[0].StationNumber}
          item={item}
          cellW={cellW}
          cellH={cellH}
          startX={startX}
          startY={startY}
          exitX={exitX}
          exitY={exitY}
          startScale={origW / cellW}
          isCurrentCard={index === sortModeStartIndexRef.current}
          isExiting={uiMode === "sort-exiting"}
          exitDelay={Math.min(index * 40, 180)}
          onPress={() => {
            exitTargetIndexRef.current = index;
            exitSortMode();
          }}
        />
      );
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [cellW, cellH, gridGap, gridPad, origW, width, carouselHeight, uiMode]
  );

  /** Sortable.Grid の onDragEnd */
  const onSortDragEnd = useCallback(
    (newOrder: { indexToKey: string[] }) => {
      // お気に入りモード以外はデータを書き換えない（安全策）
      if (stationSource.type !== "favorite") return;
      const newList = newOrder.indexToKey.map(
        (key) => listUpStation.find((s) => s[0].StationNumber === key) ?? []
      );
      setFavoriteStation(newList);
      AS.setItem(STORAGE_KEYS.FAVORITE_STATION, JSON.stringify(newList));
    },
    [listUpStation, setFavoriteStation, stationSource]
  );

  return {
    uiMode,
    startSortMode,
    exitSortMode,
    sortGridRenderItem,
    onSortDragEnd,
  };
}
