import { renderTemplate, SYSTEM_RDD } from "./constants.js";
import { Grammar } from "./grammar.js";
import { HtmlUtility } from "./html-utility.js";
import { RdDTimestamp } from "./time/rdd-timestamp.js";

const LATEST_USED_JOURNAL_ID = "chronologie-dernier-journal";

export class DialogChronologie extends foundry.applications.api.DialogV2 {
  static initSettings() {
    game.settings.register(SYSTEM_RDD, LATEST_USED_JOURNAL_ID, {
      name: "Dernier article de journal utilisé pour enregistrer la chronologie",
      scope: "client",
      config: false,
      default: "",
      type: String
    })
  }

  static async create() {
    const dialogData = {
      auteur: game.user.name,
      isGM: game.user.isGM,
      information: "",
      journalId: game.settings.get(SYSTEM_RDD, LATEST_USED_JOURNAL_ID),
      journaux: game.journal.filter(it => it.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)),
      timestamp: game.system.rdd.calendrier.timestamp,
      dateReel: game.system.rdd.calendrier.dateReel()
    }
    const content = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-chronologie.hbs", dialogData)
    const dialog = new DialogChronologie(content, dialogData)
    dialog.render({ force: true })
  }

  constructor(content, dialogData) {
    const timeData = dialogData.timestamp.toCalendrier()
    super({
      window: { title: `Chronologie - ${timeData.jourDuMois} ${timeData.mois.label} - Heure  ${timeData.heure.label}` },
      content,
      classes: ["DialogChronologie"],
      buttons: [{ action: "close", label: "Fermer", icon: "fa-solid fa-xmark", callback: () => this.close() }],
      position: { width: 500 }
    })
    this.dialogData = dialogData
  }

  _onRender(context) {
    super._onRender(context)
    const el = this.element
    const journalPrecedent = game.journal.get(this.dialogData.journalId)
    this.showChronologiePreset(!(journalPrecedent?.canUserModify(game.user)))
    el.querySelector("a.chronologie-preset-show")?.addEventListener("click", () => this.showChronologiePreset(true))
    el.querySelector("a.chronologie-preset-hide")?.addEventListener("click", () => this.showChronologiePreset(false))
    el.querySelector("button.chronologie-ajouter")?.addEventListener("click", () => this.ajouter())
  }

  showChronologiePreset(showPreset) {
    const el = this.element
    const show = (sel, v) => { const e = el.querySelector(sel); if (e) HtmlUtility.showControlWhen(e, v) }
    show(".chronologie-preset-show", !showPreset)
    show(".chronologie-preset-hide", showPreset)
    show(".chronologie-preset", showPreset)
  }

  async ajouter() {
    await this.forceValidation()
    const { journalId, journalEntry } = this.findJournal()
    if (journalEntry?.canUserModify(game.user, 'update')) {
      const journalParameters = this.extractJournalParameters()
      const jour = journalParameters.dateRdD.jour
      const mois = journalParameters.dateRdD.mois.label
      const annee = journalParameters.dateRdD.annee
      const section = `${jour} ${mois} ${annee}`
      const content = await this.prepareChronologieEntry(journalParameters)
      this.addContentToJournal(journalEntry, section, content)
      this.storeLatestUsedJournalEntry(journalId)
      this.close()
    }
    else {
      const journal = this._val(".rdddialogchrono select[name='journalId']")
      ui.notifications.warn(`Le journal ${journal} n'est pas accessible`)
    }
  }

  async forceValidation() {
    this.element.querySelectorAll(".rdddialogchrono input, .rdddialogchrono select, .rdddialogchrono textarea").forEach(el => el.dispatchEvent(new Event("change")))
  }

  _val(sel) { return this.element.querySelector(sel)?.value ?? "" }

  findJournal() {
    const journalId = this._val("[name='journalId']")
    const journalEntry = game.journal.get(journalId)
    return { journalId, journalEntry }
  }

  async prepareChronologieEntry(journalParameters) {
    return await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/chronologie-entry.hbs", journalParameters)
  }

  extractJournalParameters() {
    return {
      auteur: this._val("[name='auteur']"),
      information: this._val("[name='information']"),
      dateRdD: {
        jour: this._val("[name='chronologie.jourDuMois']"),
        mois: RdDTimestamp.definition(this._val("[name='chronologie.mois']")),
        annee: this._val("[name='chronologie.annee']"),
        heure: RdDTimestamp.definition(this._val("[name='chronologie.heure']")),
        minute: this._val("[name='chronologie.minute']"),
      },
      dateReel: this._val("[name='dateReel']").replace('T', ' ')
    }
  }

  addContentToJournal(journalEntry, section, content) {
    let page = journalEntry.pages.find(p => p.type == 'text' && Grammar.equalsInsensitive(p.name, section))
    if (page) {
      page.update({ 'text.content': page.text.content + '\n' + content })
    }
    else {
      journalEntry.createEmbeddedDocuments('JournalEntryPage', [this.newPageChronologie(section, content)])
    }
  }

  newPageChronologie(section, content) {
    return new JournalEntryPage({
      name: section,
      type: 'text',
      title: { show: true, level: 1 },
      text: { content: content, format: 1 }
    })
  }

  storeLatestUsedJournalEntry(journalId) {
    game.settings.set(SYSTEM_RDD, LATEST_USED_JOURNAL_ID, journalId)
  }
}
