import PlaceableConfig from "./placeable-config.mjs";
import Drawing from "../../canvas/placeables/drawing.mjs";
import FontConfig from "@client/applications/settings/menus/font-config.mjs";

/**
 * @import {ApplicationConfiguration, FormFooterButton} from "../_types.mjs";
 * @import {DocumentSheetConfiguration} from "../api/document-sheet.mjs";
 * @import DrawingDocument from "@client/documents/drawing.mjs";
 */

/**
 * The Application responsible for configuring a single Drawing document within a parent Scene.
 */
export default class DrawingConfig extends PlaceableConfig {

  /** @inheritDoc */
  static DEFAULT_OPTIONS = {
    classes: ["drawing-config"],
    canCreate: true,
    window: {
      contentClasses: ["standard-form"],
      icon: "fa-solid fa-pencil"
    },
    position: {width: 480},
    form: {closeOnSubmit: true}
  };

  /** @override */
  static PARTS = {
    tabs: {template: "templates/generic/tab-navigation.hbs"},
    position: {template: "templates/scene/drawing/position.hbs"},
    lines: {template: "templates/scene/drawing/lines.hbs"},
    fill: {template: "templates/scene/drawing/fill.hbs"},
    text: {template: "templates/scene/drawing/text.hbs"},
    footer: {template: "templates/generic/form-footer.hbs"}
  };

  /** @override */
  static TABS = {
    sheet: {
      tabs: [
        {id: "position", icon: "fa-solid fa-location-dot"},
        {id: "lines", icon: "fa-solid fa-paintbrush"},
        {id: "fill", icon: "fa-regular fa-fill-drip"},
        {id: "text", icon: "fa-solid fa-font"}
      ],
      initial: "position",
      labelPrefix: "DRAWING.TABS"
    }
  };

  /* -------------------------------------------- */

  /** @inheritDoc */
  _previewChanges(changes) {
    super._previewChanges(changes);
    if ( !this._preview.rendered ) return;
    const redraw = (this._preview.object.controls.shape.type !== this._preview._shape.type)
      || (this._preview.object.hasText === !this._preview.object.text);
    this._preview.object.renderFlags.set({redraw});
  }

  /* -------------------------------------------- */

  /** @inheritDoc */
  async _prepareContext(options) {
    const context = await super._prepareContext(options);
    return Object.assign(context, {
      tabClasses: "top-tabs",
      userColor: game.user.color,
      units: {
        degrees: _loc("MEASUREMENT.Degrees"),
        pixels: _loc("MEASUREMENT.Pixels")
      }
    });
  }

  /* -------------------------------------------- */

  /**
   * Configure footer buttons for this sheet.
   * @returns {FormFooterButton[]}
   */
  #prepareButtons() {
    const submitLabel = this.document.id ? "DRAWING.ACTIONS.submitUpdate" : "DRAWING.ACTIONS.submitCreate";
    return [{type: "submit", icon: "fa-solid fa-floppy-disk", label: submitLabel}];
  }

  /* -------------------------------------------- */

  /** @inheritDoc */
  async _preparePartContext(partId, context, options) {
    const partContext = await super._preparePartContext(partId, context, options);
    if ( partId in (partContext.tabs ?? {}) ) partContext.tab = partContext.tabs[partId];
    switch ( partId ) {
      case "position":
        partContext.drawingRoles = {false: _loc("DRAWING.Object"), true: _loc("DRAWING.Information")};
        break;
      case "lines":
        partContext.scaledBezierFactor = context.source.bezierFactor * 2;
        break;
      case "fill":
        partContext.fillDisabled = context.source.fillType === CONST.DRAWING_FILL_TYPES.NONE;
        partContext.fillTypes = Object.entries(CONST.DRAWING_FILL_TYPES).map(([k, v]) => ({
          value: v,
          label: _loc(`DRAWING.FILL_TYPES.${k.toLowerCase()}`)
        }));
        break;
      case "text":
        partContext.fontFamilies = FontConfig.getAvailableFontChoices();
        break;
      case "footer":
        partContext.buttons = this.#prepareButtons();
    }
    return partContext;
  }

  /* -------------------------------------------- */

  /** @override */
  _onChangeForm(formConfig, event) {
    // Toggle the disabled attribute of certain fill fields depending on the fillType.
    if (event.target.name === "fillType") {
      const disabled = Number(event.target.value) === CONST.DRAWING_FILL_TYPES.NONE;
      for (const field of this.element.querySelectorAll("[name=fillColor], [name=fillAlpha]")) {
        field.disabled = disabled;
      }
    }
    super._onChangeForm(formConfig, event);
  }

  /* -------------------------------------------- */

  /** @inheritDoc */
  _processFormData(event, form, formData) {
    const submitData = super._processFormData(event, form, formData);

    // Un-scale the bezier factor
    if ( "bezierFactor" in submitData ) submitData.bezierFactor /= 2;

    return submitData;
  }

  /* -------------------------------------------- */

  /** @inheritDoc */
  async _processSubmitData(event, form, submitData, options) {

    // Rescale dimensions if needed
    const currentShape = this.document._source.shape;
    const newShape = submitData.shape;
    if ( (newShape.width !== currentShape.width) || (newShape.height !== currentShape.height) ) {
      const dx = newShape.width - currentShape.width;
      const dy = newShape.height - currentShape.height;
      foundry.utils.mergeObject(submitData, Drawing.rescaleDimensions(this.document._source, dx, dy));
    }

    return super._processSubmitData(event, form, submitData, options);
  }
}
