using BoFilTest.Utils;
using Optional;
using System;
using System.Collections.Generic;

namespace BoFilTest.Domain
{
    public enum StepType
    {
        CakeFormation,
        Pause,
        GasBreakthrough,
        IntermediateDemoisturizing,
        Demoisturizing,
        Pressing,
        Vaporization,
        Washing,
    }
    public class StepDescription
    {
        public static TranslationKey STEP_DESCRIPTION_CAKE_FORMATION = new TranslationKey("STEP_DESCRIPTION_CAKE_FORMATION");
        public static TranslationKey STEP_SHORT_CAKE_FORMATION = new TranslationKey("STEP_SHORT_CAKE_FORMATION");

        public static TranslationKey STEP_DESCRIPTION_INTERIM_DEMOISTURIZING = new TranslationKey("STEP_DESCRIPTION_INTERIM_DEMOISTURIZING");
        public static TranslationKey STEP_SHORT_INTERIM_DEMOISTURIZING = new TranslationKey("STEP_SHORT_INTERIM_DEMOISTURIZING");

        public static TranslationKey STEP_DESCRIPTION_PAUSE = new TranslationKey("STEP_DESCRIPTION_PAUSE");
        public static TranslationKey STEP_SHORT_PAUSE = new TranslationKey("STEP_SHORT_PAUSE");

        public static TranslationKey STEP_DESCRIPTION_WASHING = new TranslationKey("STEP_DESCRIPTION_WASHING");
        public static TranslationKey STEP_SHORT_WASHING = new TranslationKey("STEP_SHORT_WASHING");

        public static TranslationKey STEP_DESCRIPTION_VAPORIZATION = new TranslationKey("STEP_DESCRIPTION_VAPORIZATION");
        public static TranslationKey STEP_SHORT_VAPORIZATION = new TranslationKey("STEP_SHORT_VAPORIZATION");

        public static TranslationKey STEP_DESCRIPTION_PRESSING = new TranslationKey("STEP_DESCRIPTION_PRESSING");
        public static TranslationKey STEP_SHORT_PRESSING = new TranslationKey("STEP_SHORT_PRESSING");

        public static TranslationKey STEP_DESCRIPTION_DEMOISTURIZING = new TranslationKey("STEP_DESCRIPTION_DEMOISTURIZING");
        public static TranslationKey STEP_SHORT_DEMOISTURIZING = new TranslationKey("STEP_SHORT_DEMOISTURIZING");

        public static TranslationKey STEP_DESCRIPTION_GAS_BREAKTHROUGH = new TranslationKey("STEP_DESCRIPTION_GAS_BREAKTHROUGH");
        public static TranslationKey STEP_SHORT_GAS_BREAKTHROUGH = new TranslationKey("STEP_SHORT_GAS_BREAKTHROUGH");

        private static readonly Dictionary<StepType, Tuple<TranslationKey, TranslationKey>> DescriptionsFor
            = new Dictionary<StepType, Tuple<TranslationKey, TranslationKey>>
        {
            {StepType.CakeFormation, Tuple.Create(STEP_DESCRIPTION_CAKE_FORMATION, STEP_SHORT_CAKE_FORMATION) },
            {StepType.IntermediateDemoisturizing, Tuple.Create(STEP_DESCRIPTION_INTERIM_DEMOISTURIZING, STEP_SHORT_INTERIM_DEMOISTURIZING) },
            {StepType.Pause, Tuple.Create(STEP_DESCRIPTION_PAUSE, STEP_SHORT_PAUSE) },
            {StepType.Washing, Tuple.Create(STEP_DESCRIPTION_WASHING, STEP_SHORT_WASHING) },
            {StepType.Vaporization, Tuple.Create(STEP_DESCRIPTION_VAPORIZATION, STEP_SHORT_VAPORIZATION) },
            {StepType.Pressing, Tuple.Create(STEP_DESCRIPTION_PRESSING, STEP_SHORT_PRESSING) },
            {StepType.Demoisturizing, Tuple.Create(STEP_DESCRIPTION_DEMOISTURIZING, STEP_SHORT_DEMOISTURIZING) },
            {StepType.GasBreakthrough, Tuple.Create(STEP_DESCRIPTION_GAS_BREAKTHROUGH, STEP_SHORT_GAS_BREAKTHROUGH) },
        };

        private readonly TranslationKey title;
        private readonly TranslationKey sign;
        private readonly Option<int> index;

        private StepDescription(StepType type, Option<int> index)
        {
            Type = type;
            this.title = DescriptionsFor[type].Item1;
            this.sign = DescriptionsFor[type].Item2;
            this.index = index;
        }

        public StepDescription(StepType type, int index)
            : this(type, index.Some())
        {
        }

        public StepDescription(StepType type)
            : this(type, Option.None<int>())
        {
        }

        private string WithIndex(TranslationKey key)
        {
            if (index.HasValue)
            {
                return Translated.FromKey(key, index.ValueOr(0) + 1);
            }
            return Translated.FromKey(key);
        }

        public bool IsRecording => Type != StepType.Pause;

        public bool IsIntegrating => Type == StepType.Vaporization || Type == StepType.GasBreakthrough || Type == StepType.Demoisturizing;

        public string Denomination => WithIndex(title);
        public string Sign => WithIndex(sign);

        public StepType Type { get; }
    }
}
