import React, { useRef, useState, useEffect, useLayoutEffect, FC } from "react";
import { Platform, View, ScrollView, LayoutAnimation } from "react-native";
import Constants from "expo-constants";
import {
  configureReanimatedLogger,
  ReanimatedLogLevel,
} from "react-native-reanimated";
import StatusbarDetect from "@/StatusbarDetect";

import { LED_vision } from "@/components/発車時刻表/LED_vidion";
import { TitleBar } from "@/components/Menu/TitleBar";
import { FixedContentBottom } from "@/components/Menu/FixedContentBottom";

import { lineList, stationIDPair } from "@/lib/getStationList";
import { useFavoriteStation } from "@/stateBox/useFavoriteStation";
import { useNavigation } from "@react-navigation/native";
import { useStationList } from "@/stateBox/useStationList";
import { TopMenuButton } from "@/components/Menu/TopMenuButton";
import { JRSTraInfoBox } from "@/components/Menu/JRSTraInfoBox";
import MapView, { Marker } from "react-native-maps";
import { CarouselBox } from "@/components/Menu/Carousel/CarouselBox";
import { CarouselTypeChanger } from "@/components/Menu/Carousel/CarouselTypeChanger";
import { useUserPosition } from "@/stateBox/useUserPosition";
import { AS } from "@/storageControl";
import { lineList_LineWebID } from "@/lib/getStationList";
import { StationProps } from "@/lib/CommonTypes";
import { LocationObject } from "expo-location";
configureReanimatedLogger({
  level: ReanimatedLogLevel.error, // Set the log level to error
  strict: true, // Reanimated runs in strict mode by default
});

type props = {
  scrollRef: React.RefObject<ScrollView>;
  mapHeight: number;
  MapFullHeight: number;
  mapMode: boolean;
  setMapMode: React.Dispatch<React.SetStateAction<boolean>>;
};
export const Menu: FC<props> = (props) => {
  const { scrollRef, mapHeight, MapFullHeight, mapMode, setMapMode } = props;
  const { navigate } = useNavigation();
  const { favoriteStation } = useFavoriteStation();
  const { originalStationList, getStationDataFromNameBase } = useStationList();
  const [stationListMode, setStationListMode] = useState<
    "position" | "favorite"
  >("position");
  useEffect(() => {
    AS.getItem("stationListMode")
      .then((res) => setStationListMode(res))
      .catch(() => {
        // AS.setItem("stationListMode", "position");
      });
  }, []);
  const mapsRef = useRef(null);
  const returnToTop = (bool = true) => {
    scrollRef?.current.scrollTo({
      y: mapHeight > 80 ? mapHeight - 80 : 0,
      animated: bool,
    });
  };
  const goToMap = () => {
    scrollRef?.current.scrollTo({
      y: 0,
      animated: true,
    });
  };
  useEffect(() => {
    setTimeout(() => {
      returnToTop(false);
    }, 10);
  }, [mapHeight]);
  const [scrollStartPosition, setScrollStartPosition] = useState(0);
  const onScrollBeginDrag = (e) => {
    LayoutAnimation.configureNext({
      duration: 300,
      create: {
        type: LayoutAnimation.Types.easeInEaseOut,
        property: LayoutAnimation.Properties.opacity,
      },
      update: {
        type: LayoutAnimation.Types.easeInEaseOut,
        property: LayoutAnimation.Properties.opacity,
      },
    });
    setScrollStartPosition(e.nativeEvent.contentOffset.y);
    setMapMode(false);
  };
  //現在地基準の駅名標リストアップ機能
  const { position, locationStatus } = useUserPosition();

  const [nearPositionStation, setNearPositionStation] = useState<
    StationProps[][]
  >([]); //第三要素

  useEffect(() => {
    if (!position) return () => {};
    makeCurrentStation(position);
  }, [position, stationListMode]);

  const makeCurrentStation = (location: LocationObject) => {
    if (!originalStationList) return () => {};
    const findStationEachLine = (selectLine) => {
      const searchArea = 0.055; //検索範囲
      const _calcDistance = (from, to) => {
        let lat = Math.abs(from.lat - to.lat);
        let lng = Math.abs(from.lng - to.lng);
        return Math.sqrt(lat * lat + lng * lng);
      };
      let NearStation = selectLine.filter(
        (d) =>
          _calcDistance(d, {
            lat: location.coords.latitude,
            lng: location.coords.longitude,
          }) < searchArea
      );
      //NearStationを距離の近い順にソート
      NearStation.sort((a, b) => {
        return (
          _calcDistance(a, {
            lat: location.coords.latitude,
            lng: location.coords.longitude,
          }) -
          _calcDistance(b, {
            lat: location.coords.latitude,
            lng: location.coords.longitude,
          })
        );
      });
      return NearStation;
    };

    let _stList: StationProps[] = lineList
      .map((d) => findStationEachLine(originalStationList[d]))
      .filter((d) => d.length > 0)
      .reduce((pre, current) => {
        pre.push(...current);
        return pre;
      }, []);
    if (_stList.length == 0) setNearPositionStation([]);
    else {
      let returnData: StationProps[][] = [];
      _stList.forEach((d, index, array) => {
        const stationName = d.Station_JP;
        if (returnData.findIndex((d) => d[0].Station_JP == stationName) != -1)
          return;
        returnData.push(array.filter((d2) => d2.Station_JP == stationName));
      });
      //returnDataを距離の近い順にソート
      returnData.sort((a, b) => {
        const _calcDistance = (from, to) => {
          let lat = Math.abs(from.lat - to.lat);
          let lng = Math.abs(from.lng - to.lng);
          return Math.sqrt(lat * lat + lng * lng);
        };
        return (
          _calcDistance(a[0], {
            lat: location.coords.latitude,
            lng: location.coords.longitude,
          }) -
          _calcDistance(b[0], {
            lat: location.coords.latitude,
            lng: location.coords.longitude,
          })
        );
      });
      setNearPositionStation(returnData);
    }
  };

  const [listIndex, setListIndex] = useState(0);

  const [listUpStation, setListUpStation] = useState<StationProps[][]>([]);
  const [isSearchMode, setisSearchMode] = useState(false);
  const [input, setInput] = useState("");
  useLayoutEffect(() => {
    if (!!isSearchMode) {
      const returnData = [];
      if (!input || input == "") {
        Object.keys(lineList_LineWebID).forEach((d) => {
          originalStationList[d].forEach((D) => {
            if (
              isSearchMode &&
              isSearchMode != stationIDPair[lineList_LineWebID[d]]
            )
              return;
            const latlng = [D.lat, D.lng];
            if (latlng.length == 0) return null;
            if (D.StationNumber == undefined) {
              return null;
            }
            returnData.push([D]);
          });
        });
      } else {
        const hoge = getStationDataFromNameBase(input);
        hoge.forEach((d, index, array) => {
          const stationName = d.Station_JP;
          if (
            returnData.findIndex((d1) => d1[0].Station_JP == stationName) != -1
          )
            return;
          returnData.push(array.filter((d2) => d2.Station_JP == stationName));
        });
      }
      if (JSON.stringify(returnData) == JSON.stringify(listUpStation)) return;
      setListUpStation(returnData);
    } else if (stationListMode == "position") {
      const returnData = nearPositionStation.filter((d) => d != undefined);
      if (JSON.stringify(returnData) == JSON.stringify(listUpStation)) return;
      setListUpStation(returnData);
    } else {
      const returnData = favoriteStation.filter((d) => d != undefined);
      if (JSON.stringify(returnData) == JSON.stringify(listUpStation)) return;
      setListUpStation(returnData);
    }
  }, [nearPositionStation, favoriteStation, stationListMode, isSearchMode]);
  useEffect(() => {
    if (listUpStation.length == 0) {
      setListIndex(0);
      return;
    }
    if (listUpStation.length == 1) {
      setListIndex(0);
      return;
    }
    if (listUpStation[listIndex] == undefined) {
      const count = listIndex - 1;
      setMapMode(false);
      setListIndex(count);
    }
  }, [listIndex, listUpStation, isSearchMode]);
  useEffect(() => {
    if (originalStationList == undefined) return;
    if (listUpStation.length == 0) return;
    if (listUpStation[listIndex] == undefined) return;
    const { lat, lng } = listUpStation[listIndex][0];
    const mapRegion = {
      latitude: lat,
      longitude: lng,
      latitudeDelta: 0.05,
      longitudeDelta: 0.05,
    };
    if (mapMode) {
      mapsRef?.current.fitToCoordinates(
        listUpStation.map((d) => ({
          latitude: d[0].lat,
          longitude: d[0].lng,
        })),
        { edgePadding: { top: 80, bottom: 120, left: 50, right: 50 } } // Add margin values here
      );
    } else {
      mapsRef.current.animateToRegion(mapRegion, 1000);
    }
  }, [listIndex, listUpStation]);

  return (
    <View
      style={{
        height: "100%",
        backgroundColor: "white",
        paddingTop: Platform.OS == "ios" ? Constants.statusBarHeight : 0,
      }}
    >
      <StatusbarDetect />
      {!mapMode ? <TitleBar /> : <></>}
      <ScrollView
        ref={scrollRef}
        snapToStart={false}
        snapToEnd={false}
        decelerationRate={"normal"}
        snapToOffsets={[mapHeight - 80]}
        // contentContainerStyle={{
        //   position: "relative",
        // }}
        onScrollBeginDrag={onScrollBeginDrag}
        onScrollEndDrag={(e) => {
          if (e.nativeEvent.contentOffset.y < mapHeight - 80) {
            if (scrollStartPosition > e.nativeEvent.contentOffset.y) {
              goToMap();
            } else {
              returnToTop();
            }
          }
        }}
      >
        <MapView
          ref={mapsRef}
          style={{ width: "100%", height: mapMode ? MapFullHeight : mapHeight }}
          showsUserLocation={true}
          loadingEnabled={true}
          showsMyLocationButton={false}
          moveOnMarkerPress={false}
          showsCompass={false}
          //provider={PROVIDER_GOOGLE}
          initialRegion={{
            latitude: 33.774519,
            longitude: 133.533306,
            latitudeDelta: 1.8, //小さくなるほどズーム
            longitudeDelta: 1.8,
          }}
          onTouchStart={() => {
            LayoutAnimation.configureNext({
              duration: 300,
              create: {
                type: LayoutAnimation.Types.easeInEaseOut,
                property: LayoutAnimation.Properties.opacity,
              },
              update: {
                type: LayoutAnimation.Types.easeInEaseOut,
                property: LayoutAnimation.Properties.opacity,
              },
            });
            setMapMode(true);
            goToMap();
          }}
        >
          {listUpStation.map(([{ lat, lng, StationNumber }], index) => (
            <Marker
              key={index + StationNumber}
              coordinate={{
                latitude: lat,
                longitude: lng,
              }}
              image={require("@/assets/reccha-small.png")}
              onPress={() => {
                setMapMode(false);
                setListIndex(index);
                if (mapsRef.current) {
                  mapsRef.current.animateToRegion(
                    {
                      latitude: lat,
                      longitude: lng,
                      latitudeDelta: 0.05,
                      longitudeDelta: 0.05,
                    },
                    1000
                  );
                }
                LayoutAnimation.configureNext({
                  duration: 300,
                  create: {
                    type: LayoutAnimation.Types.easeInEaseOut,
                    property: LayoutAnimation.Properties.opacity,
                  },
                  update: {
                    type: LayoutAnimation.Types.easeInEaseOut,
                    property: LayoutAnimation.Properties.opacity,
                  },
                });
                returnToTop();
              }}
            />
          ))}
        </MapView>
        {!mapMode && (
          <CarouselTypeChanger
            {...{
              locationStatus,
              position,
              stationListMode,
              setStationListMode,
              setSelectedCurrentStation: setListIndex,
              mapMode,
              setMapMode,
              isSearchMode,
              setisSearchMode,
              input,
              setInput,
            }}
          />
        )}

        {originalStationList.length != 0 && (
          <>
            <CarouselBox
              {...{
                originalStationList,
                listUpStation,
                nearPositionStation,
                setListIndex,
                listIndex,
                navigate,
                stationListMode,
                isSearchMode,
              }}
            />
            {listUpStation[listIndex] && (
              <LED_vision station={listUpStation[listIndex]} />
            )}
          </>
        )}

        <TopMenuButton />
        <JRSTraInfoBox />
        <FixedContentBottom navigate={navigate} />
      </ScrollView>
      {mapMode && (
        <CarouselTypeChanger
          {...{
            locationStatus,
            position,
            stationListMode,
            setStationListMode,
            setSelectedCurrentStation: setListIndex,
            mapMode,
            setMapMode,
            isSearchMode,
            setisSearchMode,
            input,
            setInput,
          }}
        />
      )}
    </View>
  );
};
