import { RawMessage, Player } from "@minecraft/server";
import { ActionFormData, MessageFormData } from "@minecraft/server-ui";
import { DisplayCondition } from "lazuli-common";

/**
 * Create an article.
 * @category Need Registry
 */
export class Article {
  constructor(
    /**
     * Id of the article.
     */
    public readonly id: string,
    /**
     * Title of the article.
     */
    public title: string | RawMessage,
    /**
     * Body of the article, support RawMessage.
     */
    public body: string | RawMessage,
    /**
     * Icon path of the article.
     */
    public iconPath?: string,
    /**
     * If true, articles will be unlocked in the {@link ArticleCollection} after reading it.
     */
    public needUnlock = true
  ) {}
  /**
   * Display the reading to a player.
   */
  display(player: Player): void {
    if (!this.checkUnlock(player)) this.unlock(player);
    const FORM = new ActionFormData()
      .title(this.title)
      .body(this.body)
      .button({ translate: "gui.ok" });
    FORM.show(player);
  }
  /**
   * Registry the prop.
   * @deprecated Use `Register.articleRegistry()` to registry the prop
   */
  protected register() {
    console.warn("[Lazuli] The register method was deprecated!");
  }
  /**
   * Unlock the article to article collection.
   * @param player
   */
  unlock(player: Player) {
    player.addTag(`articleUnlock:${this.id}`);
  }
  /**
   * Check the article whether it is unlocked or not to article collection.
   * @param player
   */
  checkUnlock(player: Player) {
    if (!this.needUnlock) {
      return true;
    } else {
      return player.hasTag(`articleUnlock:${this.id}`);
    }
  }
}

/**
 * Create an article with chapters.
 * @category Need Registry
 */
export class ChapterArticle extends Article {
  constructor(
    /**
     * Id of the article.
     */
    public readonly id: string,
    /**
     * Title of the article.
     */
    public title: string | RawMessage,
    /**
     * Body of the article, support RawMessage.
     */
    public body: string | RawMessage,
    /**
     * Chapters of the article.
     */
    public chapters: ChapterData[],
    /**
     * Icon path of the article.
     */
    public iconPath?: string,
    /**
     * If true, articles will be unlocked in the {@link ArticleCollection} after reading it.
     */
    public needUnlock = true
  ) {
    super(id, title, body, iconPath, needUnlock);
  }
  /**
   * Display the reading to a player.
   */
  display(player: Player): void {
    if (!this.checkUnlock(player)) this.unlock(player);
    const FORM = new ActionFormData().title(this.title).body(this.body);
    this.chapters.forEach((chapter) => {
      FORM.button(chapter.title, chapter.iconPath);
    });
    FORM.show(player).then((response) => {
      if (response.canceled || response.selection === undefined) {
        return;
      }
      const CHAPTER_FORM = new ActionFormData()
        .title(this.chapters[response.selection].title)
        .body(this.chapters[response.selection].body)
        .button({ translate: "gui.ok" });
      CHAPTER_FORM.show(player);
    });
  }
}

/**
 * Create an article collection.
 * It likes {@link ChapterArticle}, but support article unlock.
 * @category Need Registry
 */
export class ArticleCollection {
  constructor(
    /**
     * Id of the collection.
     */
    public readonly id: string,
    /**
     * Title of the collection.
     */
    public title: string | RawMessage,
    /**
     * Body of the collection.
     */
    public body: string | RawMessage,
    /**
     * Control when collection is displayed.
     */
    public displayCondition: DisplayCondition,
    /**
     * Articles in the collection.
     */
    public articles: (Article | ChapterArticle)[]
  ) {}
  /**
   * Display the reading to a player.
   */
  display(player: Player): void {
    let articleList: (Article | ChapterArticle)[] = [];
    const MAIN_FORM = new ActionFormData().title(this.title).body(this.body);
    this.articles.forEach((article) => {
      if (article.checkUnlock(player)) {
        MAIN_FORM.button(article.title, article.iconPath);
        articleList.push(article);
      }
    });
    if (articleList.length === 0) {
      const WARNING_FORM = new MessageFormData()
        .title({ translate: "article.nothing.title" })
        .body({ translate: "article.nothing.body" })
        .button1({ translate: "gui.ok" })
        .button2({ translate: "gui.close" });
      WARNING_FORM.show(player);
    } else {
      MAIN_FORM.show(player).then((response) => {
        if (response.canceled || response.selection === undefined) {
          return;
        }
        articleList[response.selection].display(player);
      });
    }
  }
  /**
   * Registry the prop.
   * @deprecated Use `Register.articleRegistry()` to registry the prop
   */
  protected register() {
    console.warn("[Lazuli] The register method was deprecated!");
  }
}

/**
 * Data of chapters.
 */
export interface ChapterData {
  /**
   * Title of the chapter.
   */
  title: string | RawMessage;
  /**
   * Body of the Chapter.
   */
  body: string | RawMessage;
  /**
   * Icon path of the chapter.
   */
  iconPath?: string;
}

