import { h, Component } from "preact"
import Notes, { IVault, ViewNote } from "../../../notes";
import Trash from "feather-icons/dist/icons/trash-2.svg"
import X from "feather-icons/dist/icons/x.svg"
import Save from "feather-icons/dist/icons/save.svg"

import Navigation from "../../../navigation";
import { YesNoModal } from "../../modals/YesNoModal";
import LoadingModal from "../../modals/LoadingModal";
import Notifications, { MessageType } from "../../../notifications";
import Modal from "../../modals/Modal";

const minRows = 3;
export default class EntryComponent extends Component<{ vault: Promise<IVault>, id: string | undefined, note: string | undefined }, { title: string, changed: boolean }> {
   old_text: string;
   text: string = "";
   vault: IVault;
   lineHeight: number = 24;
   note: ViewNote;

   rows: number = minRows;

   skip_save: boolean = false;

   loading?: LoadingModal;

   constructor(props) {
      super(props);
      this.state = { changed: false, title: "" };
   }

   private toVault() {
      // history.back()
      history.back();
      // Navigation.setPage("/vault", { id: this.vault.id }, { entry: "false" }, true);
   }

   async componentWillMount() {
      try {
         this.skip_save = false;
         this.loading = new LoadingModal();
         this.loading.show();

         this.vault = await this.props.vault;
         let note: ViewNote;
         let changed = false;
         if (this.props.id)
            note = await this.vault.getNote(this.props.id)
         else {
            note = this.vault.newNote();
            if (this.props.note) {
               note.__value = this.props.note;
               changed = true;
            }
         }

         if (!note) {
            Notifications.sendNotification("Note not found!", MessageType.ERROR);
            // this.toVault()
         } else {
            this.note = note;
            this.text = note.__value;
            let rows = this.getRows(this.text);
            if (rows !== this.rows) {
               this.rows = rows;
            }
            let [title] = this.text.split("\n", 1);
            this.setState({ title, changed })
            if (this.loading)
               this.loading.close();
         }
      } catch (err) {
         Notifications.sendError(err);
      }
   }

   private async save() {
      try {
         if (this.state.changed) {
            this.note.__value = this.text;
            await this.vault.saveNote(this.note);
            this.setState({ changed: false })
         }
      } catch (err) {
         Notifications.sendError(err);
      }
   }

   // async onKeypress(event) {
   //    event = event || window.event;
   //    
   // }

   componentWillUnmount() {
      if (!this.skip_save)
         this.save()
   }

   strToNr(value: string) {
      let match = value.match(/\d/g)
      return Number(match.join(""))
   }

   getRows(value: string) {
      const lines = (value.match(/\r?\n/g) || '').length + 1
      return Math.max(lines + 1, minRows);
   }

   textAreaChange(evt: KeyboardEvent) {
      if (evt.keyCode === 17 || evt.keyCode === 27) return; //No character, so not relevant for this function
      let target = (evt.target as HTMLTextAreaElement)
      let value = target.value;

      this.text = value;
      if (!this.state.changed && this.textAreaKeyPress(evt)) this.setState({ changed: true })

      let [title] = value.split("\n", 1);
      if (title !== this.state.title)
         this.setState({ title });

      let rows = this.getRows(value);
      if (rows !== this.rows) {
         target.rows = rows;
         this.rows = rows;
      }
   }

   async exitHandler() {
      if (this.state.changed) {
         let modal = new YesNoModal("Really want to quit?");
         let res = await modal.getResult();
         if (res === true) {
            this.skip_save = true;
            this.toVault();
         }
      } else
         this.toVault()
   }

   textAreaKeyPress(evt: KeyboardEvent) {
      if ((evt.keyCode === 83 || evt.keyCode === 13) && evt.ctrlKey) {
         evt.preventDefault()
         this.save();
         return false;
      }
      else if (evt.keyCode === 27) {
         evt.preventDefault();
         this.exitHandler();
         return false;
      }
      return true;
   }

   render() {
      const save_handler = async () => {
         await this.save()
         Navigation.setPage("/vault", { id: this.vault.id }, { entry: "false" }, true);
         this.toVault()
      }

      const delete_handler = async () => {
         await this.vault.deleteNote(this.props.id);
         this.toVault()
      }

      return <div>
         <header>
            <div>
               <a class="button header_icon_button" onClick={() => this.exitHandler()}><X height={undefined} width={undefined} /></a>
               {this.state.changed ? <a class="button header_icon_button" onClick={() => save_handler()}><Save height={undefined} width={undefined} /></a> : undefined}
            </div>
            <h1 style="display:inline" class="button header_title">{this.state.title}</h1>
            <a class="button header_icon_button" onClick={() => delete_handler()}><Trash height={undefined} width={undefined} /></a>
         </header>
         <div class="container">
            <div class="row">
               <div class="col-sm-12 col-md-8 col-lg-6 col-md-offset-2 col-lg-offset-3">
                  <textarea autofocus value={this.text} rows={this.rows} class="doc" style="width:100%;" onKeyDown={evt => this.textAreaKeyPress(evt)} onKeyUp={evt => this.textAreaChange(evt)} ref={elm => {
                     if (elm)
                        setTimeout(() => elm.focus(), 0)
                  }} />
               </div>
            </div>
         </div>
      </div>
   }
}