import { FC, useRef, useState, useCallback } from "react";
import {
  View,
  Text,
  ScrollView,
  useWindowDimensions,
  Vibration,
} from "react-native";
import { ExGridViewItem } from "./ExGridViewItem";
import Animated, {
  useAnimatedStyle,
  useSharedValue,
  runOnJS,
  useAnimatedScrollHandler,
  withTiming,
  Easing,
  FadeIn,
  FadeOut,
  BounceInUp,
  FadeInUp,
  FadeOutUp,
} from "react-native-reanimated";
import { Gesture, GestureDetector } from "react-native-gesture-handler";
import { ExGridViewTimePositionItem } from "./ExGridViewTimePositionItem";
import { useCurrentTrain } from "@/stateBox/useCurrentTrain";
import dayjs from "dayjs";

export const ExGridView: FC<{
  data: {
    trainNumber: string;
    array: string;
    name: string;
    type: string;
    time: string;
  }[];
}> = ({ data }) => {
  const groupedData: {
    [d: number]: {
      trainNumber: string;
      array: string;
      name: string;
      type: string;
      time: string;
      isOperating: boolean;
    }[];
  } = {"4":[],
    "5":[],
    "6":[],
    "7":[],
    "8":[],
    "9":[],
    "10":[],
    "11":[],
    "12":[],
    "13":[],
    "14":[],
    "15":[],
    "16":[],
    "17":[],
    "18":[],
    "19":[],
    "20":[],
    "21":[],
    "22":[],
    "23":[],
    "0":[],
    "1":[],
    "2":[],
    "3":[]
  };
  const groupKeys: string[] = ["4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","0","1","2","3"];

  const { width } = useWindowDimensions();
  const { currentTrain } = useCurrentTrain();
  data.forEach((item) => {
    let isOperating = false;
    let [hour, minute] = dayjs()
          .hour(parseInt(item.time.split(":")[0]))
          .minute(parseInt(item.time.split(":")[1]))
          .format("H:m")
          .split(":");
    if (currentTrain.findIndex((x) => x.num == item.trainNumber) != -1) {
      const currentTrainTime = currentTrain.find(
        (x) => x.num == item.trainNumber
      )?.delay;
      if (currentTrainTime != "入線") {
        [hour, minute] = dayjs()
          .hour(parseInt(hour))
          .minute(parseInt(minute))
          .add(parseInt(currentTrainTime), "minute")
          .format("H:m")
          .split(":");
      }
      isOperating = true;
    }
    // if (!groupedData[hour]) {
    //   groupedData[hour] = [];
    //   groupKeys.push(hour);
    // }
    groupedData[hour].push({ ...item, time: `${hour}:${minute}`, isOperating });
  });
  // ドラッグ位置を保持する共有値
  const widthX = useSharedValue(width);
  const savedWidthX = useSharedValue(width);
  const isChanging = useSharedValue(false);
  const animationProgress = useSharedValue(0); // アニメーション進行度
  const [scrollEnabled, setScrollEnabled] = useState(true);
  const scrollRef = useRef<Animated.ScrollView>(null);

  // ScrollViewの有効/無効を切り替える関数
  const toggleScrollEnabled = useCallback((enabled: boolean) => {
    setScrollEnabled(enabled);
  }, []);

  // パンジェスチャー（ドラッグ）のハンドラー
  const pinchGesture = Gesture.Pinch()
    .onUpdate((e) => {
      const calc = savedWidthX.value * e.scale;
      widthX.value = calc > width ? calc : width;
      //runOnJS(scrollToRightEnd)();
    })
    .onEnd(() => {
      savedWidthX.value = widthX.value;
    });

  const gesture = Gesture.Pan()
    .minPointers(2) // 最低2本指
    .maxPointers(2) // 最大2本指
    .onStart(() => {
      runOnJS(toggleScrollEnabled)(false);
    })
    .onEnd(() => {
      runOnJS(toggleScrollEnabled)(true);
      savedWidthX.value = widthX.value;
    });
  const longPressGesture = Gesture.Pan()
    .minPointers(1)
    .maxPointers(1)
    .activateAfterLongPress(200)
    .onStart(() => {
      runOnJS(Vibration.vibrate)(30);
      isChanging.value = true;
    })
    .onUpdate((e) => {
      const calc = widthX.value + e.velocityY;
      widthX.value = calc > width ? calc : width;
    })
    .onEnd(() => {
      console.log("Long press ended");
      isChanging.value = false;
    });

  // ジェスチャーを組み合わせる
  const composed = Gesture.Simultaneous(
    longPressGesture,
    pinchGesture,
    gesture
  );

  // アニメーションスタイル
  const animatedStyle = useAnimatedStyle(() => ({
    width: widthX.value,
    backgroundColor: isChanging.value ? "#8adeffff" : "white",
  }));
  // 時ヘッダーを横にスクロールしたときの処理
  const scrollX = useSharedValue(0);
  const scrollHandler = useAnimatedScrollHandler({
    onScroll: (event) => {
      scrollX.value = event.contentOffset.x;
    },
  });
  const stickyTextStyle = useAnimatedStyle(() => ({
    transform: [{ translateX: scrollX.value }],
  }));
  const animatedLongPressStyle = useAnimatedStyle(() => ({
    display: isChanging.value ? "flex" : "none",
  }));
  return (
    <>
      <Animated.View
        style={[
          {
            position: "absolute",
            width,
            backgroundColor: "#26d1baff",
            zIndex: 500,
            top:0 
          },
          animatedLongPressStyle,
        ]}
         entering={FadeInUp} exiting={FadeOutUp} 
      >
        <Text style={{ fontSize: 30, textAlign: "center", flex: 1 }}>
          ↑縮小　・　拡大↓
        </Text>
      </Animated.View>
      <GestureDetector gesture={composed}>
        <Animated.ScrollView
          horizontal
          nestedScrollEnabled
          pinchGestureEnabled={false}
          scrollEnabled={scrollEnabled}
          onScroll={scrollHandler}
          onContentSizeChange={(contentWidth) => {
            // 現在のスクロール位置を取得
            const currentScrollX = scrollX.value;
            const containerWidth = width - 50;

            // コンテンツが画面からはみ出している場合のみ右端にスクロール
            if (currentScrollX + containerWidth > contentWidth) {
              const newScrollX = Math.max(0, contentWidth - containerWidth);
              scrollRef.current?.scrollTo({ x: newScrollX, animated: true });
            }
          }}
          ref={scrollRef}
          contentContainerStyle={{
            flexDirection: "column",
            backgroundColor: "white",
          }}
        >
          <Animated.View
            style={[
              {
                width: width,
                flexDirection: "row",
              },
              animatedStyle,
            ]}
          >
            {Array.from({ length: 60 }, (_, i) => i + 1).map((num) => {
              if (num % 5 === 0) {
                return (
                  <Text
                    key={num}
                    style={{
                      flex: 1,
                      textAlign: "left",
                      borderRightWidth: 0.5,
                      borderColor: "#ccc",
                      flexWrap: "nowrap",
                      fontSize: 12,
                    }}
                  >
                    {num - 5}
                  </Text>
                );
              } else return <></>;
            })}
            <Text
              style={{
                textAlign: "right",
                borderRightWidth: 0.5,
                borderColor: "#ccc",
                flexWrap: "nowrap",
                fontSize: 12,
                width: 50,
              }}
            >
              (分)
            </Text>
          </Animated.View>
          <Animated.ScrollView
            style={[{ width: width }, animatedStyle]}
            pinchGestureEnabled={false}
            minimumZoomScale={0.5}
            maximumZoomScale={3.0}
            scrollEnabled={scrollEnabled}
            stickyHeaderIndices={
              groupKeys.at(0) ? groupKeys.map((_, i) => i * 2) : []
            }
          >
            {groupKeys.map((hour) => [
              <View
                style={{
                  padding: 5,
                  borderBottomWidth: 0.5,
                  borderTopWidth: 0.5,
                  borderBottomColor: "#ccc",
                  backgroundColor: "#f0f0f0",
                }}
                key={hour}
              >
                <Animated.Text
                  style={[
                    {
                      fontSize: 15,
                      zIndex: 1,
                      marginLeft: 0,
                    },
                    stickyTextStyle,
                  ]}
                >
                  {hour}時台
                </Animated.Text>
              </View>,
              <View style={{ flexDirection: "row", position: "relative", height: 50  }}>
                {groupedData[hour].map((d, i, array) => (
                  <ExGridViewItem
                    key={d.trainNumber + i}
                    d={d}
                    index={i}
                    width={widthX}
                    array={array}
                  />
                ))}
                <ExGridViewTimePositionItem width={widthX} hour={hour} />
              </View>,
            ])}
          </Animated.ScrollView>
        </Animated.ScrollView>
      </GestureDetector>
    </>
  );
};
