import React, { useState, useEffect } from "react";

import "./Carousel.css";

import { IconButton, Button } from "../../index";

import { IconLeftArrow } from "../../svg_icons/IconLeftArrow";
import { IconRightArrow } from "../../svg_icons/IconRightArrow";

import { getCN, isMasive, getClassName } from "../utils";

function Carousel({
  children,
  pagination = false,
  autoPlay = true,
  counter = true, // Вклчюает счетчик
  counterVisible = 4000, //таймер пропадания счётчика, false - выключает пропадание
  size = 200,
  autoPlayTime = 5000,
  playClickTime = 10000, //false - Выключает автоматическое продолжение карусели
  switches = true,
  switchesVisible = 3000, //false - выключает пропадание
  ripple = false,
  type = `defailt`,
  ...props
}: {
  [x: string]: any;
  switchesVisible?: false | number;
  counterVisible?: false | number;
  type?: "defailt" | "mushroom";
  size?: number;
}) {
  const [currentIndex, setCurrentIndex] = useState(0);
  const [length, setLength] = useState(children.length);
  const [touchPosition, setTouchPosition] = useState(null);

  const [visible_counter, setVisibleCounter] = useState(false);
  const [visible_switches, setVisibleSwitches] = useState(true);

  const [is_autoplay, setAutoPlay] = useState(true);

  const [is_click, setIs_click] = useState(false);
  const [is_hover, setIs_hover] = useState(false);

  useEffect(() => {
    setLength(children.length);
    if (!children[0]) {
      autoPlay = false;
    }
    return;
  }, [children]);

  useEffect(() => {
    if (currentIndex < 0) {
      setCurrentIndex(0);
    } else if (currentIndex >= length - 1) {
      setCurrentIndex(length - 1);
    }
    return;
  }, [currentIndex]);

  useEffect(() => {
    if (counterVisible) {
      if (!is_autoplay) {
        //counter
        setVisibleCounter(true);
        var timer = setTimeout(() => setVisibleCounter(false), counterVisible);

        return () => {
          clearTimeout(timer);
        };
      }
    }
    return;
  }, [currentIndex, is_hover]);

  useEffect(() => {
    if (switchesVisible) {
      if (!is_autoplay) {
        //switches
        setVisibleSwitches(true);
        var timer = setTimeout(
          () => setVisibleSwitches(false),
          switchesVisible
        );

        return () => {
          clearTimeout(timer);
        };
      }
    }
    return;
  }, [currentIndex, is_hover]);

  const next = async (id = 1, auto = false) => {
    await setAutoPlay(auto);
    if (currentIndex < length - 1)
      await setCurrentIndex((prevState) => prevState + id);
  };

  const prev = async (id = 1, auto = false) => {
    await setAutoPlay(auto);
    if (currentIndex > 0) await setCurrentIndex((prevState) => prevState - id);
  };

  const onTouchStart = (e: any) => setTouchPosition(e.touches[0].clientX);

  const onTouchMove = (e: any) => {
    if (touchPosition === null) return;
    const currentPosition = e.touches[0].clientX;
    var direction = touchPosition - currentPosition;

    if (direction > 7) {
      if (currentIndex < length - 1) next(1);
    }

    if (direction < -7) {
      if (currentIndex > 0) prev(1);
    }
    setIs_click(true);
    setTouchPosition(null);
  };
  useEffect(() => {
    if (!playClickTime) return;
    const onsetIs_click = () => {
      setIs_click(false);
    };
    const interval = setInterval(() => {
      onsetIs_click();
    }, playClickTime);

    return () => {
      clearInterval(interval);
    };
  }, [is_click]);

  useEffect(() => {
    if (!playClickTime) return;
    var currentIndex_time = currentIndex;
    var children_length = length - 1;
    var playStatus = currentIndex_time < children_length ? true : false;

    if (children_length == undefined) {
      setCurrentIndex(0);
      autoPlay = false;
      return;
    }

    const reloadStatick = () => {
      if (currentIndex_time > children_length) {
        currentIndex_time = currentIndex_time - children_length;
        if (currentIndex_time < 0) currentIndex_time = 0;
        playStatus = true;
        return setCurrentIndex(currentIndex_time);
      }
    };

    reloadStatick();

    if (is_click) return;
    if (!autoPlay) return;

    const interval = setInterval(async () => {
      reloadStatick();
      if (playStatus) {
        currentIndex_time++;
        if (currentIndex_time >= children_length) playStatus = false;
        next(1, true);
      } else {
        currentIndex_time--;
        if (currentIndex_time <= 0) playStatus = true;
        prev(1, true);
      }
    }, autoPlayTime);

    return () => {
      clearInterval(interval);
    };
  }, [length, is_click]);

  const transformInfo = () => {
    if (type === "mushroom") {
      if (currentIndex == 0) return `translateX(calc(-${currentIndex * 100
        }% + var(--padding_content) * 7))`;

      if (currentIndex + 1 == length)
        return `translateX(calc(-${currentIndex * 100
          }% + (var(--padding_content) * 19.5 + var(--padding_content)) * ${currentIndex} )`;

      return `translateX(calc(-${currentIndex * 100
        }% + var(--padding_content) * 25))`;
    }
    if (currentIndex == 0) return `translateX(0px)`;

    if (currentIndex + 1 == length)
      return `translateX(calc(-${currentIndex * 100
        }% + (var(--padding_content) * 2 + var(--padding_content)) * ${currentIndex} )`;

    return `translateX(calc(-${currentIndex * 100
      }% + var(--padding_content) * 2.5))`;
  };

  return (
    <div
      {...props}
      onMouseEnter={() => {
        setAutoPlay(false);
        setIs_hover(true);
      }}
      onMouseLeave={() => {
        setAutoPlay(false);
        setIs_hover(false);
      }}
      data-type={type}
      data-pagination={pagination}
      className={getCN(["MYUI-Carousel"], props.className)}
    >
      <div className="MYUI-Carousel__in">
        <div className="MYUI-Carousel__in--wrapper">
          {counter && (
            <div
              data-visible={visible_counter}
              className={getClassName(`Carousel__in--counter`)}
            >
              {currentIndex + 1}/{length}
            </div>
          )}
          <div
            onTouchStart={onTouchStart}
            onTouchMove={onTouchMove}
            data-is_one={!isMasive(children)}
            className="MYUI-Carousel__in--contents"
            style={{
              height: size,
              transform: transformInfo(),
            }}
          >
            {isMasive(children)
              ? children.map((a: any, index: any) => (
                <div
                  key={index}
                  data-rotate={type == "mushroom" && currentIndex == index ? `CENTER` : currentIndex < index ? `RIGHT` : `LEFT`}
                  className="MYUI-Carousel__in--content"
                  data-active={currentIndex == index}
                >
                  {a}
                </div>
              ))
              : children}
          </div>
        </div>
        {switches && (
          <div
            onTouchStart={onTouchStart}
            onTouchMove={onTouchMove}
            data-visible={visible_switches}
            className="MYUI-Carousel__in--IconButton"
          >
            <div
              onClick={async () => {
                setIs_click(true);
                await prev();
              }}
              className="MYUI-Carousel__in--before"
            >
              <IconButton
                data-is_active={currentIndex > 0}
                aria-label="before arrow"
                ripple={ripple}
                onClick={async () => {
                  setIs_click(true);
                  await prev();
                }}
                className="MYUI-Carousel__in--before__in"
              >
                <IconLeftArrow width={24} height={24} />
              </IconButton>
            </div>
            <div
              onClick={async () => {
                setIs_click(true);
                await next();
              }}
              className="MYUI-Carousel__in--after"
            >
              <IconButton
                data-is_active={currentIndex < length - 1}
                aria-label="afte arrow"
                ripple={ripple}
                onClick={async () => {
                  setIs_click(true);
                  await next();
                }}
                className="MYUI-Carousel__in--after__in"
              >
                <IconRightArrow width={24} height={24} />
              </IconButton>
            </div>
          </div>
        )}
      </div>
      {pagination && (
        <div className="MYUI-Carousel__pagination">
          {isMasive(children) &&
            children.map((a: any, index: number) => (
              <>
                {index == 0 && (
                  <Button
                    size={`low`}
                    aria-label="active paginaton"
                    style={{
                      transform: getTransformActive(currentIndex, length),
                    }}
                    mode="primary"
                  ></Button>
                )}
                {index != 0 && (
                  <Button
                    size={`low`}
                    aria-label="paginaton"
                    style={{
                      transform: getTransform(currentIndex, length, index),
                    }}
                    mode={"secondary"}
                    onClick={() => {
                      setCurrentIndex(
                        currentIndex >= index ? index - 1 : index
                      );
                      setIs_click(true);
                    }}
                  ></Button>
                )}
              </>
            ))}
        </div>
      )}
    </div>
  );
}

function getTransformActive(currentIndex: any, length: any) {
  if (currentIndex == 0) return `translateX(calc(0px))`;
  return `translateX(calc((var(--padding_default) + var(--paggination-size)) * ${currentIndex}))`;
}

function getTransform(currentIndex: any, length: any, index: any) {
  if (currentIndex == 0) return `translateX(calc(0px))`;
  var send: any;
  for (var i = 1; i < length - 1; i++) {
    if (currentIndex + i == index) send = `translateX(calc(0px))`;
  }
  if (send) return send;
  return `translateX(calc(
    (var(--padding_default) - var(--padding_default) * 2)
     - var(--paggination-size)))`;
}

export default Carousel;
