import {NumberField, ObjectField, StringField} from "@common/data/fields.mjs";
import VFXComponent from "../vfx-component.mjs";
import {VFXReferenceField, VFXReferencePointField} from "../fields/_module.mjs";

/**
 * @typedef VFXScrollingTextData
 * @property {{x: number, y: number}} origin   The canvas point where the text originates
 * @property {string} content                  The text string to display
 * @property {number} duration                 The duration of the scrolling effect in milliseconds (default 2000)
 * @property {number} [distance]               The distance in pixels the text travels; defaults to twice the text size
 * @property {number} textAnchor               An anchor point in CONST.TEXT_ANCHOR_POINTS (default CENTER)
 * @property {number} scrollDirection          The direction the text scrolls in CONST.TEXT_ANCHOR_POINTS (default TOP)
 * @property {number} jitter                   Randomization between [0, 1] applied to the initial position (default 0)
 * @property {object} textStyle                Additional PIXI.TextStyle parameters applied to the text
 */

/**
 * A component for displaying scrolling text effects at a canvas location using the
 * `CanvasInterfaceGroup#createScrollingText` API.
 * This can be used for damage numbers, status effects, or other floating text animations.
 *
 * @example Damage number above a token
 * ```js
 * const vfxConfig = {
 *   name: "damageNumber",
 *   components: {
 *     text: {
 *       type: "scrollingText",
 *       origin: {reference: "target"},
 *       content: "-12",
 *       duration: 1500,
 *       scrollDirection: CONST.TEXT_ANCHOR_POINTS.TOP,
 *       textStyle: {fill: "#ff4444", fontSize: 28, fontWeight: "bold"}
 *     }
 *   },
 *   timeline: [{component: "text"}]
 * };
 * const effect = new foundry.canvas.vfx.VFXEffect(vfxConfig);
 * const target = game.user.targets.first();
 * effect.play({target: target.center});
 * ```
 * @extends {VFXComponent<VFXScrollingTextData>}
 */
export default class VFXScrollingTextComponent extends VFXComponent {

  /** @override */
  static TYPE = "scrollingText";

  /** @inheritDoc */
  static defineSchema() {
    return {
      ...super.defineSchema(),
      content: new VFXReferenceField(new StringField({required: true, blank: false})),
      distance: new VFXReferenceField(new NumberField({nullable: false})),
      duration: new VFXReferenceField(new NumberField({required: true, nullable: false, initial: 2000})),
      jitter: new VFXReferenceField(new NumberField({required: true, nullable: false, initial: 0})),
      origin: new VFXReferencePointField({required: true}),
      scrollDirection: new VFXReferenceField(new NumberField({
        required: true,
        nullable: false,
        initial: CONST.TEXT_ANCHOR_POINTS.TOP,
        validate: v => Object.values(CONST.TEXT_ANCHOR_POINTS).includes(v),
        validationError: "must be one of CONST.TEXT_ANCHOR_POINTS values"
      })),
      textAnchor: new VFXReferenceField(new NumberField({
        required: true,
        nullable: false,
        initial: CONST.TEXT_ANCHOR_POINTS.CENTER,
        validate: v => Object.values(CONST.TEXT_ANCHOR_POINTS).includes(v),
        validationError: "must be one of CONST.TEXT_ANCHOR_POINTS values"
      })),
      textStyle: new VFXReferenceField(new ObjectField())
    };
  }

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

  /** @override */
  async _draw() {
    this.timeline.call(() => {
      canvas.interface.createScrollingText(this.origin, this.content, {
        anchor: this.textAnchor,
        direction: this.scrollDirection,
        distance: this.distance,
        duration: this.duration,
        jitter: this.jitter,
        ...this.textStyle
      });
    }, 0);
    this.timeline.label("end", this.duration);
  }
}
