import { h, Component } from "preact";
import { IVault, ViewNote } from "../../../notes";
import { Trash2 as Trash, X, Save } from "preact-feather";

import Navigation from "../../../navigation";
import { YesNoModal } from "../../modals/YesNoModal";
import Notifications, { MessageType } from "../../../notifications";
import CodeMirror from "../../CodeMirror";
import { useEffect, useMemo, useState } from "preact/hooks";
import { usePromise } from "../../../hooks";

interface IEntryProps {
   vault: IVault;
   id?: string;
   note?: string;
}

export default function Entry(props: IEntryProps) {
   const [changed, setChanged] = useState(false);

   const [text, setText] = useState("");
   const title = useMemo(() => text?.split("\n", 1)[0], [text]);

   const [loading, error, note] = usePromise(async () => {
      let note: ViewNote;
      if (props.id) {
         note = await props.vault.getNote(props.id);
      } else {
         note = props.vault.newNote();
         if (props.note) {
            note.__value = props.note;
            setChanged(true);
         }
      }

      if (!note) {
         Notifications.sendNotification("Note not found!", MessageType.ERROR);
         history.back();
      } else {
         setText(note.__value);
      }

      return note;
   }, [props.vault, props.id]);

   if (loading) {
      return <div>Loading entry</div>;
   } else {
      const save = async () => {
         try {
            if (changed) {
               note.__value = text;
               await props.vault.saveNote(note);
               setChanged(false);
            }
         } catch (err) {
            Notifications.sendError(err);
         }
      };

      const del = async () => {
         await props.vault.deleteNote(props.id);
         history.back();
      };

      const close = async () => {
         if (changed) {
            let modal = new YesNoModal("Really want to quit?");
            let res = await modal.getResult();
            if (!res) return;
         }
         history.back();
      };

      // TODO: Add warning on possibly unwanted exit
      useEffect(() => {
         const keyevent = (evt: KeyboardEvent) => {
            if (evt.key === "s" && evt.ctrlKey) {
               evt.preventDefault();
               save();
               return false;
            } else if (evt.key === "Escape") {
               evt.preventDefault();
               close();
               return false;
            }
            return true;
         };

         document.addEventListener("keydown", keyevent);
         return () => {
            document.removeEventListener("keydown", keyevent);
         };
      });

      return (
         <div>
            <header class="header" style="margin-bottom: 0;">
               <a class="header-icon-button" onClick={close}>
                  <X height={undefined} width={undefined} />
               </a>
               {changed && (
                  <a
                     class="header-icon-button"
                     style="margin-left: 0.5em;"
                     onClick={save}
                  >
                     <Save height={undefined} width={undefined} />
                  </a>
               )}
               <h3 style="display:inline" class="button header-title">
                  {title}
               </h3>
               <a class="header-icon-button" onClick={del}>
                  <Trash height={undefined} width={undefined} />
               </a>
            </header>
            <div class="container" style="padding: 0">
               <CodeMirror
                  value={text}
                  onChange={(value) => {
                     setChanged(true);
                     setText(value);
                  }}
                  // onSave={save}
                  // onClose={close}
               />
            </div>
         </div>
      );
   }
}
