/*
 * 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, SCTranslations} from '../../general/i18n.js';
import {SCOrganizationWithoutReferences} from '../organization.js';
import {SCPersonWithoutReferences} from '../person.js';
import {SCInPlace} from './place.js';
import {SCISO8601DateRange} from './range.js';
import {SCThing, SCThingMeta, SCThingTranslatableProperties, SCThingWithoutReferences} from './thing.js';

/**
 * Default price without distinction
 */
export interface SCPriceGroup {
  /**
   * Default price of the thing
   * @sortable price
   * @float
   */
  default: number;
}

/**
 * Price distinctions for academic context
 */
export interface SCAcademicPriceGroup extends SCPriceGroup {
  /**
   * Price for employees
   * @sortable price
   * @float
   */
  employee?: number;

  /**
   * Price for guests
   * @sortable price
   * @float
   */
  guest?: number;

  /**
   * Price for students
   * @sortable price
   * @float
   */
  student?: number;
}

/**
 * A thing without references that can be offered
 */
export interface SCThingThatCanBeOfferedWithoutReferences extends SCThingWithoutReferences {
  /**
   * Translations of a thing that can be offered
   */
  translations?: SCTranslations<SCThingThatCanBeOfferedTranslatableProperties>;
}

/**
 * A thing that can be offered
 */
export interface SCThingThatCanBeOffered<T extends SCPriceGroup>
  extends SCThing,
    SCThingThatCanBeOfferedWithoutReferences {
  /**
   * List of offers for that thing
   */
  offers?: Array<SCThingThatCanBeOfferedOffer<T>>;

  /**
   * Translations of a thing that can be offered
   */
  translations?: SCTranslations<SCThingThatCanBeOfferedTranslatableProperties>;
}

/**
 * Offer of a thing
 */
export interface SCThingThatCanBeOfferedOffer<T extends SCPriceGroup> extends SCInPlace {
  /**
   * Availability of an offer
   */
  availability: SCThingThatCanBeOfferedAvailability;

  /**
   * The time when the thing is available.
   */
  availabilityRange?: SCISO8601DateRange;

  /**
   * List of prices that are distinct for specific groups
   */
  prices?: T;

  /**
   * Provider of an offer
   */
  provider: SCThingThatCanBeOfferedProvider;
}

/**
 * Translatable properties of a thing that can be offered
 */
export interface SCThingThatCanBeOfferedTranslatableProperties extends SCThingTranslatableProperties {
  /**
   * Availability of an offer
   * @keyword
   */
  'offers[].availability'?: string;
}

/**
 * Entity responsible for the offer
 */
export type SCThingThatCanBeOfferedProvider = SCOrganizationWithoutReferences | SCPersonWithoutReferences;

/**
 * Availability of an Offer
 */
export type SCThingThatCanBeOfferedAvailability =
  | 'in stock'
  | 'out of stock'
  | 'online only'
  | 'limited availability';

/**
 * Meta information about a thing without references that accepts payments
 */
export class SCThingThatCanBeOfferedMeta<T extends SCPriceGroup>
  implements SCMetaTranslations<SCThingThatCanBeOffered<T>>
{
  /**
   * Translations of fields
   */
  fieldTranslations = {
    de: {
      ...new SCThingMeta().fieldTranslations.de,
      offers: 'Angebote',
    },
    en: {
      ...new SCThingMeta().fieldTranslations.en,
      offers: 'offers',
    },
  };

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