import { useState } from "react";
import { resolveResource } from "@tauri-apps/api/path";
import { readTextFile } from "@tauri-apps/api/fs";
import { invoke } from '@tauri-apps/api/tauri'
import Modal from "react-modal";
import { platform } from '@tauri-apps/api/os';
import "./App.css";
import { Command } from '@tauri-apps/api/shell'
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faGitAlt } from "@fortawesome/free-brands-svg-icons/faGitAlt";
import { PhysicalPosition, appWindow } from "@tauri-apps/api/window";

// TODO: Keyboard usage

// const codes = JSON.parse(await readTextFile(await resolveResource("resources/codes.json")));



type Code = {
  code: number;
  type: string;
  text: string;
};

// Set window to above the mouse cursor
// TODO: Fix for MacOS
invoke('get_mouse_pos', {}).then((posJson: any) => {
  let pos = JSON.parse(posJson);
  appWindow.innerSize().then((size: any) => {
    pos.y -= size.height + 32 /*Standard windows titlebar height*/;
    console.log(JSON.stringify(pos));
    appWindow.setPosition(new PhysicalPosition(pos.x, pos.y));
  });

});

Modal.setAppElement("#root");

function App() {
  const [codes, setCodes] = useState<Array<Code>>();
  const [subTopic, setSubTopic] = useState<string>("");
  const [configModalOpen, setConfigModalOpen] = useState<boolean>(false);
  const [droneId, setDroneId] = useState<string>(() => {
    let storedId = localStorage.getItem("droneId");
    return (storedId ? storedId : "0000");
  });

  if (!codes){
    resolveResource("resources/codes.json").then((path: string) => {
      readTextFile(path).then((codesJson: string) => {
        setCodes(JSON.parse(codesJson));
      });
    });
  }

  const getSubjects = (input: Array<Code>) => {
    // TODO: Put all single-level elements at bottom
    let subjects: Array<string> = [];
    input.forEach((code: Code) => {
      if (!subjects.includes(code.type)) {
        subjects.push(code.type)
      }
    });
    return subjects;
  };

  const getTopicChildren = (topic: string) => {
    let topicChildren: Array<string> = [];
    if (codes){
      codes.forEach((code: Code) => {
        if (code.type == topic) {
          if (!topicChildren.includes(code.text)) {
            topicChildren.push(code.text)
          }
        }
      });
    }
    return topicChildren;
  };

  const generatePayload = (code: Code) => {
    let assembledStr: string = droneId.toString();
    let codeId: string = code.code.toString();
    if (code.code < 10) {
      codeId = "00" + codeId;
    }else if (code.code < 100) {
      codeId = "0" + codeId;
    }
    assembledStr += " :: Code " + codeId;
    assembledStr += " :: " + code.type;
    if (code.text != "."){
      assembledStr += " :: " + code.text;
    }
    console.log(assembledStr);
    return assembledStr;
  };

  const handleSubClick = (topic: string, index: number) => {
    if (codes){
      let text = getTopicChildren(topic)[index];
      let filtered = codes.filter((code: Code) => code.type === topic && code.text === text);
      if (filtered.length == 1) {
        let payload: string = generatePayload(filtered[0]);
        setSubTopic("");
        invoke('type_str', {input: payload});
      }
    }
  };

  const SubMenu = () => {
    if (subTopic == "") {
      return (<div></div>);
    } else {
      return (
        <div className="col-8 menu">
          {getTopicChildren(subTopic).map((text: string, index: number, topics: Array<string>) => {
            let displayText: string = text;
            displayText = displayText.replace(/.*:: /, "");
            if (displayText == "") {
              displayText = "...";
            }
            return(
              <div
                className={`row sub-element ${(topics.length-1 == index) ? "last" : ""}`}
                key={index}
                onClick={() => {
                  handleSubClick(subTopic, index)
                }}
              >
                {displayText}
              </div>
            )
          })}
        </div>
      );
    }
  }

  const handleTopicClick = (type: string) => {
    if (codes) {
      let filtered = codes.filter((code: Code) => code.type === type);
      if (filtered.length == 1) {
        let assembledStr: string = generatePayload(filtered[0]);
        setSubTopic("");
        invoke('type_str', {input: assembledStr});
      }else{
        // Open Submenu for type
        setSubTopic(type);
      }
    }
  };

  const buildMenu = () => {
    if (codes) {
      return (
        <div>
          {getSubjects(codes).map((type: string, index: number) => {
            let dispType: string = type;
            let filtered = codes.filter((code: Code) => code.type === type);
            if (filtered.length == 1) {
              dispType += ((filtered[0].text == "")?" :: ...":((filtered[0].text == ".")?"":(" :: "+filtered[0].text)));
            }
            return (
              <input
                className={`item ${(filtered.length == 1)?"individual":""}`}
                key={index}
                type="button"
                onClick={() =>  {
                  handleTopicClick(type)
                }}
                value={dispType}
                />
            );
          })}
        </div>
      );
    }else{
      return (<div></div>);
    }
  };

  return (
    <div className="container">
      <Modal
        isOpen={configModalOpen}
        contentLabel="Configuration"
        overlayClassName="config-overlay"
        className="config-modal"
      >
        <div className="row">
          <h1 className="col-12">
            <a href="">Drone Input Tool</a>
          </h1>
        </div>
        <div className="row">
          <h2 className="col-12">
            Hexcorp Drone Interface
          </h2>
        </div>
        <div className="row">
          <div className="col-6 text-end">
            Drone ID
          </div>
          <div className="col-6 drone-id-input">
            <input
              type="text"
              value={droneId}
              onChange={(e) => {
                setDroneId(e.target.value);
                localStorage.setItem("droneId", e.target.value);
              }}
            />
          </div>
          {/* TODO: Optional auto-send on pre-made messages */}
        </div>
        <div className="row modal-footer">
          <div className="col-4" onClick={() => {
            let url = "https://git.corrupt.link/liz/AllenWrench";
            platform().then((os: string) => {
              switch(os) {
                case "win32":
                  new Command("open-link-win", ["-Command", "Start-Process", `${url}`]).spawn();
                  break;
                case "linux":
                  new Command("open-link-linux", ["-c", "xdg-open", `${url}`]).spawn();
                  break;
                case "macos":
                  new Command("open-link-macos", ["-c", "open", `${url}`]).spawn();
                  break;
                default:
                  console.log(`Unknown OS: ${os}`);
                  break;
              }
              setConfigModalOpen(false);
            });

          }}>
            <FontAwesomeIcon className="icon" icon={faGitAlt} size="2x" />
          </div>
          <div className="col-8 text-end modal-close" onClick={() => {
            setConfigModalOpen(false);
          }}>
            Close
          </div>
        </div>
      </Modal>
      <div className="row">
        <div className="col-4">
          {buildMenu()}
        </div>
        <SubMenu/>
      </div>
      <div className="row footer">
        <div className="col-12 footer-content" onClick={()=>{
          setSubTopic("");
          console.log(`Config modal open ${configModalOpen}`);
          setConfigModalOpen(!configModalOpen);
        }}>
          {droneId}
        </div>
      </div>
    </div>
  );
}

export default App;
