/*
 * Copyright (C) 2019-2022 Open StApps
 * This program 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, version 3.
 *
 * This program 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
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */
import {SCMetaTranslations} from '../general/i18n.js';
import {SCThing, SCThingMeta, SCThingType, SCThingWithoutReferences} from './abstract/thing.js';

/**
 * A tour without references
 */
export interface SCTourWithoutReferences extends SCThingWithoutReferences {
  /**
   * Init script for the tour
   * @text
   */
  init?: string;

  /**
   * Steps of a tour
   */
  steps: SCTourStep[];

  /**
   * Type of a tour
   * @keyword
   */
  type: SCThingType.Tour;
}

/**
 * A tour
 * @validatable
 * @indexable
 */
export interface SCTour extends SCTourWithoutReferences, SCThing {
  /**
   * Type of a tour
   */
  type: SCThingType.Tour;
}

/**
 * Meta information about a tour
 */
export class SCTourMeta extends SCThingMeta implements SCMetaTranslations<SCTour> {
  /**
   * Translations of fields
   */
  fieldTranslations = {
    de: {
      ...new SCThingMeta().fieldTranslations.de,
      init: 'Initiales Skript',
      steps: 'Schritte',
    },
    en: {
      ...new SCThingMeta().fieldTranslations.en,
      init: 'initial script',
      steps: 'steps',
    },
  };

  /**
   * Translations of values of fields
   */
  fieldValueTranslations = {
    de: {
      ...new SCThingMeta().fieldValueTranslations.de,
      type: 'Tour',
    },
    en: {
      ...new SCThingMeta().fieldValueTranslations.en,
      type: SCThingType.Tour,
    },
  };
}

/**
 * A step in a tour
 */
export type SCTourStep = SCTourStepMenu | SCTourStepLocation | SCTourStepTooltip;

/**
 * A location of a tour step
 */
export interface SCTourStepLocation {
  /**
   * Location to go to
   * @keyword
   */
  location: string;

  /**
   * Type of the step
   */
  type: 'location';
}

/**
 * A tooltip in a tour step
 */
export interface SCTourStepTooltip {
  /**
   * Whether the tooltip may fail or not
   */
  canFail?: boolean;

  /**
   * Element that the tooltip shall be pointing at or a list of elements to try in the specified order
   * @keyword
   */
  element: string | string[];

  /**
   * Position of the tooltip
   */
  position?: 'bottom' | 'left' | 'right' | 'top';

  /**
   * How the step shall be resolved
   */
  resolved?: SCTourResolvedElement | SCTourResolvedEvent | SCTourResolvedLocation | SCTourResolvedMenu;

  /**
   * Text that the tooltip shall contain
   * @text
   */
  text: string;

  /**
   * How often it shall be retried
   * @integer
   */
  tries?: number;

  /**
   * Type of the step
   */
  type: 'tooltip';
}

/**
 * Menu interaction of a tour step
 */
export interface SCTourStepMenu {
  /**
   * The action that needs to be completed on the menu
   */
  action: 'close';

  /**
   * The side of the menu that the step refers to
   */
  side: 'right';

  /**
   * The type of the step
   */
  type: 'menu';
}

/**
 * Tour step resolved by an element
 */
export interface SCTourResolvedElement {
  /**
   * Element name
   * @keyword
   */
  element: string;
}

/**
 * Tour step resolved by an event
 */
export interface SCTourResolvedEvent {
  /**
   * Event name
   * @keyword
   */
  event: string;
}

/**
 * Tour step resolved by a location
 */
export interface SCTourResolvedLocation {
  /**
   * Matching location
   */
  location: SCTourResolvedLocationTypeIs | SCTourResolvedLocationTypeMatch;
}

/**
 * Tour step resolved by a location for a specific location
 */
export interface SCTourResolvedLocationTypeIs {
  /**
   * Specific location name
   * @keyword
   */
  is: string;
}

/**
 * Tour step resolved by a location for a specific location
 */
export interface SCTourResolvedLocationTypeMatch {
  /**
   * Regex location name
   * @keyword
   */
  match: string;
}

/**
 * Tour step resolved by interacting with a menu
 */
export interface SCTourResolvedMenu {
  /**
   * Menu location
   */
  menu: 'open-left' | 'open-right';
}
