import React, { useState, useContext, useEffect } from "react";
import { useNavigate, useLocation, useParams } from "react-router-dom";
import { useCookies } from "react-cookie";
import classes from "../assets/styles/newForm.module.scss";
import MyButton from "../components/MyButton.jsx";
import AnswerModal from "../components/AnswerModal.jsx";
import PreviewModal from "../components/PreviewModal.jsx";
import Loading from "../components/Loading.jsx";
import { FormsData, TypeAnswerData } from "../context";
import { listFormsApi, updateTitleFormApi } from "../hooks/api/listFormsApi.js";
import { UserData } from "../context";
import {
  saveFormApi,
  addFormBlockApi,
  listFormBlockApi,
  updateBlockApi,
  updateOrderBlockApi,
  removeBlockApi,
  getBlockApi,
} from "../hooks/api/formApi.js";
import {
  responseDataToListBlock,
  numberingBlocks,
} from "../hooks/sundry/parseListBlock.js";
import MyInput from "../components/MyInput.jsx";

const NewForm = () => {
  const navigate = useNavigate();
  const location = useLocation();
  const { formId } = useParams();
  const {user, setUser} = useContext(UserData);
  const [dragElem, setDragElem] = useState(null);
  const [dropElem, setDropElem] = useState(null);
  const [loading, setLoading] = useState(false);

  const [cookies, _, __] = useCookies(["user"]);

  const { forms, setForms } = useContext(FormsData);
  const { listTypeAnswer, setListTypeAnswer } = useContext(TypeAnswerData);

  const nextID = (list, param) => {
    return list.length ? list.at(-1)[param] + 1 : 1;
  };
  const [question, setQuestion] = useState("");
  const [comment, setComment] = useState("");
  const [mandatory, setMandatory] = useState(false);
  const [optionAnswer, setOptionAnswer] = useState([]);
  const [file, setFile] = useState([]);
  const [video, setVideo] = useState("");
  const [currentTypeAnswer, setCurrentTypeAnswer] = useState("");
  const [currentOptionAnswer, setCurrentOptionAnswer] = useState("");

  const [datetime, setDatetime] = useState("");
  const [newTitleForm, setNewTitleForm] = useState("");
  const [oldTitleFrom, setOldTitleForm] = useState("");

  const [listBlock, setListBlock] = useState([]);

  const [stateModal, setStateModal] = useState(false);

  function cleanStates() {
    setStateModal(false);
    setQuestion("");
    setComment("");
    setOptionAnswer([]);
    setFile([]);
    setVideo("");
    setCurrentTypeAnswer("");
    setCurrentOptionAnswer("");
    setMandatory(false);
  }

  useEffect(() => {
    async function totalData() {
      const responseForms = await listFormsApi(cookies.token);
      const responseBlock = await listFormBlockApi(cookies.token, formId);

      if (
        responseBlock.status === 200 &&
        responseBlock.data &&
        responseForms.status === 200
      ) {
        console.log(responseDataToListBlock(responseBlock.data))
        setListBlock(responseDataToListBlock(responseBlock.data));
        const title = responseForms.data.find(
          (item) => item.id === formId
        ).title;
        setNewTitleForm(title);
        setOldTitleForm(title);
      } 
      else if (responseForms.status === 401 || responseBlock.status === 401) {
        // navigate("/enter")
        setUser(false)
      }
      else {
        setListBlock([]);
        setNewTitleForm("Новыя форма");
        setOldTitleForm("Новыя форма");
      }
      setLoading(true);
    }

    totalData();
  }, []);

  function addOptionAnswer() {
    setOptionAnswer(
      numberingBlocks(
        [
          ...optionAnswer,
          {
            id: nextID(optionAnswer, "id"),
            text: currentOptionAnswer,
          },
        ],
        "id",
        1
      )
    );
    setCurrentOptionAnswer("");
  }

  function removeOptionAnswer(id) {
    setOptionAnswer(
      numberingBlocks(
        [...optionAnswer].filter((answer) => answer.id !== id),
        "id",
        1
      )
    );
  }

  function editAnswerByForm(id) {
    const obj = listBlock.find((item) => item.id === id);
    setQuestion(obj.question);
    setComment(obj.comment);
    setFile(obj.file);
    setVideo(obj.video);
    setCurrentTypeAnswer(obj.typeAnswer);
    setOptionAnswer(obj.optionAnswer);
    setMandatory(obj.mandatory);
    setStateModal(obj.id);
    console.log(obj.file.map(item => item.name))
  }

  async function updateBlock() {
    const data = {
      question: question,
      comment: comment,
      file: file,
      video: video,
      mandatory: mandatory,
      optionAnswer: optionAnswer,
      typeAnswer: currentTypeAnswer,
    };

    const response = await updateBlockApi(
      cookies.token,
      formId,
      data,
      listBlock.find((item) => item.id === stateModal).order
    );

    if (response.status === 200) {
      const responseBlock = await listFormBlockApi(cookies.token, formId);

      if (responseBlock.status === 200) {
        setListBlock(responseDataToListBlock(responseBlock.data));
      } else {
        setListBlock([]);
      }
    } 
    else if (
      response.status === 401
    ) {
      // navigate("/enter")
      setUser(false)
    }
    else {
      console.log(response)
    } 

    cleanStates();
  }

  async function removeBlock(order) {
    const response = await removeBlockApi(cookies.token, formId, order);

    if (response.status === 200) {
      setListBlock([...listBlock.filter((item) => item.order !== order)]);
    } 
    else if (
      response.status === 401
    ) {
      // navigate("/enter")
      setUser(false)
    }
    else {
      console.log(response)
    }
  }

  async function addFiles(newFile) {
    const fileData = []

    for (let item of newFile) {
      let binary = ""
      const buff = await item.arrayBuffer()
      const bytesArray = new Uint8Array(buff)
      let len = bytesArray.byteLength;

      for (let i = 0; i < len; i++) {
        binary += String.fromCharCode( bytesArray[ i ] );
      }

      fileData.push({
        name: item.name,
        type: item.type,
        binary: btoa(binary)
      })

      setFile([...file, ...fileData])
    }
  }

  async function addFormBlock() {

    const newBlock = {
      question: question,
      typeAnswer: currentTypeAnswer,
      comment: comment,
      mandatory: mandatory,
      optionAnswer: optionAnswer,
      file: file,
      video: video,
    };

    const response = await addFormBlockApi(cookies.token, formId, newBlock);

    if (response.status === 200) {
      const responseBlock = await listFormBlockApi(cookies.token, formId);

      if (responseBlock.status === 200) {
        setListBlock(responseDataToListBlock(responseBlock.data));
      } else {
        setListBlock([]);
      }
    } 
    else if (
      response.status === 401
    ) {
      // navigate("/enter")
      setUser(false)
    }
    else {
      console.log(response)
    }
    cleanStates();
  }

  // async function updateTitleForm() {
  //     const response = await updateTitleFormApi(cookies.token, formId, newTitleForm);

  //     if (response.status === 200) {
  //         console.log(response)
  //     }
  //     else {
  //         console.log(response)
  //     }
  // };

  async function updateOrderBlock() {
    const response = await updateOrderBlockApi(cookies.token, formId, {
      new: dropElem,
      old: dragElem,
    });

    if (response.status === 200) {
      const currentElem = listBlock[dragElem];
      const tListBlock = [...listBlock];

      if (dragElem > dropElem) {
        tListBlock.splice(dropElem, 0, currentElem);
        tListBlock.splice(dragElem + 1, 1);
      } else {
        tListBlock.splice(dropElem + 1, 0, currentElem);
        tListBlock.splice(dragElem, 1);
      }

      setListBlock(numberingBlocks(tListBlock, "order"));
    }
    else if (
      response.status === 401
    ) {
      // navigate("/enter")
      setUser(false)
    }
    else {
      console.log(response)
    }
  }

  async function saveForm() {
    if (oldTitleFrom !== newTitleForm) {
      const response = await updateTitleFormApi(cookies.token, formId, newTitleForm);

      if (
        response.status === 401
      ) {
        // navigate("/enter")
        setUser(false)
      }
      else {
        console.log(response)
      }
    }

    cleanStates();
    navigate("/forms");
  }

  return (
    <div className={classes.main}>
      <div className={classes.wrapper}>
        <div className={classes.header}>
          <div className={classes.header__listInput}>
            {/* <div className={classes.header__listInput__date}>
              <span>Дедлайн выполнения</span>
              <MyInput
                type={"datetime-local"}
                value={datetime}
                change={setDatetime}
              />
            </div> */}
            <div className={classes.header__listInput__title}>
              <span>Название формы</span>
              <MyInput
                type={"text"}
                value={newTitleForm}
                change={setNewTitleForm}
              />
            </div>
          </div>
          <div className={classes.header__listBtn}>
            <MyButton
              text={"Предпросмотр"}
              class={"main__white"}
              toggle={"modal"}
              target={"#previewModal"}
            />
            <MyButton
              text={"Опубликовать"}
              class={"main__blue"}
              click={location.state ? updateFormByForms : saveForm}
            />
          </div>
        </div>
        <div className={classes.content}>
          <div className={classes.content__listQuestion}>
            <div className={classes.content__listQuestion__list}>
              {listTypeAnswer.map((item, i) => (
                <div
                  className={classes.content__listQuestion__list__item}
                  data-bs-toggle="modal"
                  data-bs-target="#answerModal"
                  onClick={() => setCurrentTypeAnswer(item.id)}
                  key={i}
                >
                  <span>{item.text}</span>
                </div>
              ))}
            </div>
          </div>

          <PreviewModal listBlock={listBlock} listTypeAnswer={listTypeAnswer} />

          <AnswerModal
            stateModal={stateModal}
            currentTypeAnswer={currentTypeAnswer}
            question={question}
            comment={comment}
            mandatory={mandatory}
            optionAnswer={optionAnswer}
            setOptionAnswer={setOptionAnswer}
            file={file}
            video={video}
            setVideo={setVideo}
            currentOptionAnswer={currentOptionAnswer}
            listTypeAnswer={listTypeAnswer}
            setQuestion={setQuestion}
            setComment={setComment}
            setFile={setFile}
            setCurrentOptionAnswer={setCurrentOptionAnswer}
            setMandatory={setMandatory}
            cleanStates={cleanStates}
            addFormBlock={addFormBlock}
            addOptionAnswer={addOptionAnswer}
            updateBlock={updateBlock}
            setCurrentTypeAnswer={setCurrentTypeAnswer}
            removeOptionAnswer={removeOptionAnswer}
            addFiles={addFiles}
          />

          <div className={classes.content__newForm}>
            <div className={classes.content__newForm__title}>
              <h3>Новая форма</h3>
            </div>
            <div className={classes.content__newForm__list}>
              {loading ? (
                listBlock.map((item, i) => (
                  <div
                    className={classes.content__newForm__list__item}
                    key={i}
                    id={item.order}
                    draggable="true"
                    onDragOver={(event) => {
                      event.preventDefault();
                    }}
                    onDragStart={(event) => {
                      if (event.target.id) {
                        setDragElem(Number(event.target.id));
                      }
                    }}
                    onDragEnter={(event) => {
                      if (event.target.id) {
                        setDropElem(Number(event.target.id));
                      }
                    }}
                    onDrop={() => updateOrderBlock()}
                  >
                    <div
                      className={classes.content__newForm__list__item__answer}
                    >
                      <span>{item.question}</span>
                      <span>
                        {listTypeAnswer.map((typeItem) => {
                          if (typeItem.id === item.typeAnswer) {
                            return typeItem.text;
                          }
                        })}
                      </span>
                    </div>
                    <div className={classes.content__newForm__list__item__btn}>
                      <i
                        class="fa-solid fa-pen"
                        data-bs-toggle="modal"
                        data-bs-target="#answerModal"
                        onClick={() => {
                          editAnswerByForm(item.id);
                        }}
                      ></i>
                      <i
                        class="fa-solid fa-trash"
                        onClick={() => removeBlock(item.order)}
                      ></i>
                    </div>
                  </div>
                ))
              ) : (
                <Loading />
              )}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

export default NewForm;