import { FlatList, Text, TouchableOpacity, View } from "react-native";
import Card from "../../Components/Card";
import {
  AppContext,
  AppSelectedUserDevice,
  AppStyles,
  Constants,
  GetDevice,
  VibrateShort,
} from "../../utils";
import { useCallback, useContext, useState } from "react";
import MyDropdown from "../../Components/Dropdown";
import MyIcon from "../../Components/Icon";
import { useTranslation } from "react-i18next";
import MyResult from "../../Components/Result";
import { MyIconButton, MyTextButton } from "../../Components/Button";
import { useFocusEffect } from "@react-navigation/native";
import { Divider } from "../../Components/Divider";
import { MyColorSwatch } from "../../Components/ColorPicker";
import { MyDotsModal } from "../../Components/Modal";
import DraggableFlatList, {
  ScaleDecorator,
} from "react-native-draggable-flatlist";

export default function SceneView({ navigation }) {
  const appContext = useContext(AppContext);
  const { t } = useTranslation();

  const [device, setDevice] = useState();
  const [isDotsModalOpen, setIsDotsModalOpen] = useState(false);

  const getSelectedDeviceSceneName = () => {
    let scene;

    if (device.selectedScene !== "") {
      scene = appContext.deviceScenes.find(
        (s) => s.sceneId === device.selectedScene
      );
    }

    return scene === undefined
      ? t("screens.device.scenes.dropdownSceneSelection.noSceneSelected")
      : scene.name;
  };

  useFocusEffect(
    useCallback(() => {
      setDevice(GetDevice(appContext.devices));

      if (device !== undefined) {
        navigation.setOptions({
          headerRight: () =>
            device.selectedScene !== "" ? (
              <MyIconButton
                iconName="dots-vertical"
                iconSize={24}
                style={AppStyles.headerNavigationIcons}
                onPress={() => setIsDotsModalOpen(true)}
              />
            ) : null,
        });
      }
    }, [device])
  );

  if (device === undefined) return <></>;

  const deviceSceneActions = appContext.deviceSceneActions.filter(
    (a) => a.sceneId === device.selectedScene
  );

  return (
    <>
      <Card>
        <MyDropdown
          label={t("screens.device.scenes.dropdownSceneSelection.label")}
          onPress={() =>
            navigation.navigate("modalChooseScene", {
              device: { selectedScene: device.selectedScene },
            })
          }
          selectedItemLabel={getSelectedDeviceSceneName()}
        />
      </Card>

      {device.selectedScene === "" ? (
        <MyResult
          text={t("screens.device.scenes.infoNoSceneSelected")}
          iconName={"selection-search"}
        />
      ) : (
        <DraggableFlatList
          scrollEnabled={false}
          data={deviceSceneActions}
          simultaneousHandlers
          onDragEnd={({ data }) =>
            // TODO: api: save sorting new order
            appContext.setDeviceSceneActions((arr) => {
              let newArr = [...arr];

              newArr = arr.filter(
                (a) => a.sceneId !== deviceSceneActions[0].sceneId
              );

              data.forEach((item) => newArr.push(item));

              return newArr;
            })
          }
          keyExtractor={(item) => item.actionId}
          ListEmptyComponent={
            <MyResult
              text={t("screens.device.scenes.infoNoActionsAvailableInScene")}
              iconName={"selection-search"}
            />
          }
          ListFooterComponent={
            <MyTextButton
              title={t("screens.device.scenes.buttonAddAction")}
              styleContainer={{
                alignItems: "center",
                marginTop: 10,
              }}
              style={{ padding: 8 }}
              actionColor={
                deviceSceneActions === undefined ||
                deviceSceneActions.length === 0
              }
              onPress={() =>
                navigation.navigate("modalAddSceneAction", {
                  deviceFirmwareVersion: device.firmware.version,
                })
              }
              iconName="plus-circle-outline"
            />
          }
          renderItem={({ item, drag }) => {
            return (
              <ScaleDecorator>
                <ActionListItem
                  drag={drag}
                  navigation={navigation}
                  device={device}
                  item={item}
                />
              </ScaleDecorator>
            );
          }}
          onRelease={VibrateShort}
        />
      )}

      <MyDotsModal
        isOpen={isDotsModalOpen}
        closeModal={() => setIsDotsModalOpen(false)}
        data={[
          {
            icon: "pencil",
            label: "Change scene name",
            onPress: () =>
              navigation.navigate("modalUpdateSceneName", {
                deviceSelectedScene: device.selectedScene,
                sceneName: getSelectedDeviceSceneName(),
              }),
          },
          {
            icon: "trash-can",
            label: "Delete scene",
            onPress: () => {
              appContext.setDeviceScenes((scenes) =>
                scenes.filter(
                  (scene) =>
                    scene.sceneId !==
                    GetDevice(appContext.devices).selectedScene
                )
              );

              appContext.setDevices((arr) => {
                const newArr = [...arr];

                const foundDeviceIndex = arr.findIndex(
                  (d) => d.id === AppSelectedUserDevice.current.id
                );

                if (foundDeviceIndex !== -1) {
                  newArr[foundDeviceIndex].selectedScene = "";

                  appContext.setDeviceSceneActions((actions) =>
                    actions.filter(
                      (action) =>
                        action.sceneId !==
                        newArr[foundDeviceIndex].selectedScene
                    )
                  );
                }

                return newArr;
              });
            },
          },
        ]}
      />
    </>
  );
}

function ActionListItem({ drag, navigation, device, item }) {
  const appContext = useContext(AppContext);

  const ListItemTitle = () => {
    return (
      <Text
        style={{
          color: appContext.appTheme.colors.primary,
        }}
      >
        {item.modeId === ""
          ? "???"
          : appContext.deviceFirmwareModes.lightModes.find(
              (lM) => lM.id === item.modeId
            ).name[appContext.appLanguage]}
      </Text>
    );
  };

  const getAnimationText = (animationInOrOutList, itemId, itemAdjustment) => {
    const usedAnimation = animationInOrOutList.find((lA) => lA.id === itemId);

    return `${usedAnimation.name[appContext.appLanguage]} (${
      itemAdjustment[usedAnimation.adjustment.variableName]
    }${usedAnimation.adjustment.unitOfMeasurement[appContext.appLanguage]})`;
  };

  const ListItemAdjustments = () => {
    let adjustments = [];

    if (
      item.type === Constants.actionType.layers &&
      item.modeAdjustments.layers !== undefined
    ) {
      adjustments.push(
        <View style={{ flexDirection: "row", alignItems: "center" }}>
          <Text style={{ color: appContext.appTheme.textSecondary }}>
            {appContext.deviceFirmwareModes.lightModes.find(
              (lM) => lM.id === item.modeId
            ).defaults.length === 0
              ? `Apply to layer ${item.modeAdjustments.layers.join(", ")}`
              : ` Set layer ${item.modeAdjustments.layers.join(", ")} to ${
                  item.modeAdjustments.colors.length === 0 ? "???" : ""
                }`}
          </Text>

          {item.modeAdjustments.colors !== undefined &&
            item.modeAdjustments.colors.map((color, index) => (
              <MyColorSwatch
                key={index}
                backgroundColor={color}
                size={16}
                style={{ marginRight: -2 }}
              />
            ))}
        </View>
      );
    }

    if (
      item.animationInId !== Constants.defaultAnimationId ||
      item.animationOutId !== Constants.defaultAnimationId
    ) {
      let inAndOutAnimation = [];

      if (item.animationInId !== Constants.defaultAnimationId) {
        inAndOutAnimation.push(
          getAnimationText(
            appContext.deviceFirmwareModes.lightAnimationsIn,
            item.animationInId,
            item.animationInAdjustment
          )
        );
      }

      if (item.animationOutId !== Constants.defaultAnimationId) {
        inAndOutAnimation.push(
          getAnimationText(
            appContext.deviceFirmwareModes.lightAnimationsOut,
            item.animationOutId,
            item.animationOutAdjustment
          )
        );
      }

      adjustments.push(
        <View style={{ flexDirection: "row", alignItems: "center", gap: 6 }}>
          <MyIcon name="transition" size={16} />
          <Text style={{ color: appContext.appTheme.textSecondary }}>
            {inAndOutAnimation.join(", ")}
          </Text>
        </View>
      );
    }

    return adjustments.map((adjustment, index) => (
      <View key={index} style={{ flexDirection: "row" }}>
        {adjustment}
      </View>
    ));
  };

  return (
    <View style={{ marginLeft: 15, marginRight: 15 }}>
      <TouchableOpacity
        onPress={() =>
          navigation.navigate("modalLayersEditAction", {
            actionId: item.actionId,
            deviceFirmwareVersion: device.firmware.version,
          })
        }
      >
        <View
          style={{
            flexDirection: "row",
            alignItems: "center",
            justifyContent: "space-between",
          }}
        >
          <View style={{ flexDirection: "row" }}>
            <MyIcon
              name={ActionTypeIconName(item.type)}
              size={24}
              style={item.modeId !== "" && { marginTop: 6 }}
            />

            <View style={{ marginLeft: 12 }}>
              <ListItemTitle />

              {item.modeId !== "" && <ListItemAdjustments />}
            </View>
          </View>

          <TouchableOpacity
            onLongPress={() => {
              drag();
              VibrateShort();
            }}
            style={{ padding: 4 }}
          >
            <MyIcon name="menu" size={20} />
          </TouchableOpacity>
        </View>

        <Divider />
      </TouchableOpacity>
    </View>
  );
}

export function ActionTypeIconName(actionType) {
  let iconName = "";

  switch (actionType) {
    case Constants.actionType.layers:
      iconName = "lightbulb-on-outline";
      break;
    case Constants.actionType.ambilight:
      iconName = "television-ambient-light";
      break;
    case Constants.actionType.motor:
      iconName = "axis-z-rotate-counterclockwise";
      break;
    case Constants.actionType.waitXSeconds:
      iconName = "timer-sand";
      break;
    case Constants.actionType.waitUntilTimeX:
      iconName = "clock-time-eight-outline";
      break;
    case Constants.actionType.stop:
      iconName = "pause-octagon-outline";
      break;
    case Constants.actionType.timeControl:
      iconName = "timer-cog";
      break;
    case Constants.actionType.waitForConfirmationWithKey:
      iconName = "gesture-tap-button";
      break;
    case Constants.actionType.jumpToScene:
      iconName = "debug-step-over";
      break;
    default:
      iconName = "help";
      break;
  }

  return iconName;
}
