/*
Copyright 2023 0xf8.dev@proton.me

This file is part of Galerie

Galerie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Galerie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Galerie. If not, see <https://www.gnu.org/licenses/>.
*/

import App from "./app";
import React from "react";

import jQuery from "jquery";
const $ = jQuery;

import Settings, { apiUrl } from "./settings";

const settings = new Settings();

let global_ActivePopout: Popout = null;


class Popout {
  private element: JQuery<HTMLImageElement>;
  private overlay: JQuery<HTMLElement>;

  constructor(element: JQuery<HTMLImageElement>, src: string) {
    this.element = element.clone();

    this.element.removeClass("resourceh resource");
    this.element.addClass("popout");
    this.element.css("opacity", 0.0001);

    this.element.on("load", () => {
      console.log(this.element.height() > this.element.width(), this.element.height(), this.element.width());

      if (this.element.height() > this.element.width())
        if (screen.orientation.type == "portrait-primary" || screen.orientation.type == "portrait-secondary")
          this.element.css("width", "94vw");
        else
          this.element.css("height", "94vh");


      if (this.element.width() >= this.element.height())
        this.element.css("width", "96vw");

        this.element.css("opacity", 1);
    });

    this.overlay = $("<div class='overlay' scroll='no'>");
    this.overlay.append(this.element);
  }

  create() {
    if (global_ActivePopout != null) return;
    global_ActivePopout = this;

    $("root").append(this.overlay);
    this.overlay.one("click", (event) => {
      event.preventDefault();

      this.destroy();
    });
  }

  destroy() {
    if (global_ActivePopout != this) return;
    global_ActivePopout = null;

    this.overlay.remove();
    this.element.remove();
  }
}

// ===============
// === Gallery ===
// ===============

class gallery {
  constructor() {}

  public async load(): Promise<void> {
    console.log("Loading gallery");
    
    await settings.cache.load();
  }

  public async loadDisplay(data: string[]): Promise<void> {
    await this.clearDisplay();

    if (settings.config.get("onlyFavorites")) {
      let d = [];

      for (let i in data) {
        let j = data[i];
        if (await settings.favorites.contains(j)) d.push(j);
      }

      data = d;
    }

    if (!settings.config.get("ignoreBlacklist")) {
      let d = [];

      for (let i in data) {
        let j = data[i];
        if (!await settings.blacklist.contains(j)) d.push(j);
      }

      data = d;
    }

    if (data.length != 0) {
      for (let i = 0; i < data.length; i++) {
        let f = await data.at(i);

        if (!settings.config.get("ignoreBlacklist"))
          if (await settings.blacklist.contains(f)) continue;

        this.createElement(f).then((e) => e.appendTo($("div#display")));
      }
    } else {
      let t = $(
        `<span style='margin-top: 3em'>There's nothing here${settings.config.get("onlyFavorites") ? "" : ". <a style='color: white; text-decoration: none' href='#' id='a'>Reload?</a>"}${
          settings.config.get("onlyFavorites")
            ? "<br>Hint: 'onlyFavorites' is enabled. <a style='color: white; text-decoration: none' href='#' id='dar'>Disable and reload?</a>"
            : ""
        }${await settings.blacklist.at(0) ? '<br>Hint: Every image is blacklisted' : ""}</span>`
      );

      t.children("a#a").on("click", async (e) => {
        e.preventDefault();
        this.loadDisplay(await settings.cache.order());
      });

      t.children("a#dar").on("click", async (e) => {
        e.preventDefault();
        settings.config.set("onlyFavorites", false);
        this.loadDisplay(await settings.cache.order());
      })
      $(t).appendTo($("div#display"));
    }
  }

  private async clearDisplay(): Promise<void> {
    $("#display").children().remove();
  }

  private async createElement(src: string): Promise<JQuery<HTMLElement>> {
    let container = $("<span>");
    let element: JQuery<HTMLImageElement> = $(`<img class='resource resourceh'>`);
    element.prop("loop", true);
    element.prop("nocontrols", true);
    element.attr("src", `${apiUrl}img/${src}`);

    let popoutHandler = async (event) => {
      event.preventDefault();

      const popout = new Popout(element, src);

      popout.create();
    };

    element.on("click", popoutHandler);

    let ialist: JQuery<HTMLElement>;
    let reloadlist = async () => {
      ialist = await this.createIconActionList(container, src, reloadlist);

      container.children("span").remove();
      container.append(ialist);
    };

    container.append(element);
    ialist = await this.createIconActionList(container, src, reloadlist);
    ialist.css("opacity", 0);

    container.append(ialist);

    element.on("load", (e) => {
      ialist.removeAttr("style");
    });

    // await reloadlist();

    return container;
  }

  private async createIconActionList(e:JQuery<HTMLElement>, src: string, triggerReload) {
    let container = $("<span>");

    let ia = (icon: string, title: string, func: () => void) => {
      let i = $(`<i title="${title}" class="${icon}">`);
      i.on("click", func);
      container.append(i);
    };

    if (await settings.favorites.contains(src)) {
      ia("fa-solid fa-heart", "Unfavorite", () => {
        settings.favorites.delete(src);
        triggerReload();
      });
    } else {
      ia("fa-regular fa-heart", "Favorite", () => {
        settings.favorites.push(src);
        triggerReload();
      });
    }


    if (settings.config.get("ignoreBlacklist")) {
      if (await settings.blacklist.contains(src)) {
        ia("fa-solid fa-eye-slash", "De-blacklist", () => {
          settings.blacklist.delete(src);
          triggerReload();
        });
      } else {
        ia("fa-solid fa-eye", "Blacklist", () => {
          settings.blacklist.push(src);
          triggerReload();
        });
      }
    } else {
      ia("fa-solid fa-ban", "Blacklist", () => {
        settings.blacklist.push(src);
        e.remove();
        triggerReload();
      })
    }

    return container;
  }
}

let Gallery = new gallery();

window.onload = async () => {
  await Gallery.load();

  await Gallery.loadDisplay(await settings.cache.order());
};

const root = App(() => {
  return (
    <>
      <div id="container">
        <div id="display"></div>
      </div>
    </>
  );
});