// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2022, Hiperscan GmbH Dresden, Germany
//
//    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, either version 3 of the License, or
//    (at your option) any later version.
//
//    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 <http://www.gnu.org/licenses/>.

using System;

using Hiperscan.Unix;
using Hiperscan.ApoIdentCore.SectionManager.Substance.SubstanceSelection;
using Hiperscan.ApoIdentCore.SectionManager.Pharmacy.Fields;
using Hiperscan.ApoIdentCommon.ApoConfig;

namespace Hiperscan.ApoIdentCore.SectionManager.Pharmacy
{
    public class PharmacyManager : ISectionManager
    {
        public event EventHandler ArchiveMissed = null;
        public event EventHandler ProfileSettingsCheckNeeded = null;
        public event EventHandler CompleteStateChanged = null;

        public PharmacyManager(ProfileManager all_profile_settings)
        {
            this.ProfileManager = all_profile_settings;

            foreach (ProfileSettings profile in this.ProfileManager.AllProfiles.Values)
                profile.CheckMissingArchive();

            this.Operator.ValidStateChanged += (sender, e) => this.SetCompletionState();
        }

        public void CheckArchive()
        {
            if (this.ProfileManager.CurrentProfile == null)
                return;

            if (this.ProfileManager.CurrentProfile.ArchiveMissing == false)
                return;

            this.ArchiveMissingMessage = String.Format(Catalog.GetString(
@"The Apo-Ident archive directory ""{0}"" for configuration profile ""{1}"" is unavailable. This may be a temporary problem with a network resource or removable storage device.

- You can create a new archive in the <i>settings -> report settings</i>
- or you close this application and restore the archive and restart the software.

If you continue anyway, all data for this profile of this session will be get lost after closing application."
            ),
                                                       this.ProfileManager.CurrentProfile.Archive,
                                                       this.ProfileManager.CurrentProfile.Name);

            this.ArchiveMissed?.Invoke(this, EventArgs.Empty);
        }

        public void CreateArchive(ProfileSettings profile)
        {
            if (this.ProfileManager.CurrentProfile == null)
                return;

            profile.ArchiveMissing = false;

            try
            {
                FileIO.CreateDirectory(profile.Archive);

                profile.CreateMetaDataDir();
                profile.LoadCacheData(true);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Cannot create archive '{0}': {1}", this.ProfileManager.CurrentProfile.Archive, ex);
            }
        }

        public void CheckSettings()
        {
            if (this.ProfileManager.CurrentProfile == null)
                this.ProfileSettingsCheckNeeded?.Invoke(this, EventArgs.Empty);
        }

        private void SetCompletionState()
        {
            this.IsComplete = this.ProfileManager.CurrentProfile != null && this.Operator.IsEntryValid;
        }

        public void UpdateAfterSubstanceSelection(SubstancesCatalog substances_catalog)
        {
            if (substances_catalog.SelectionType == SubstanceSelectionType.ThirdParty)
            {
                this.Operator.FireEvent = false;
                this.Operator.Entry = substances_catalog.ExchangeData.User;
                this.Operator.FireEvent = true;
            }

            this.ProfileManager.CurrentProfile?.SetAutpCompletionsInitialValues(substances_catalog.Substance);
            this.SetCompletionState();
        }

        public void Clear()
        {
        }

        public void Reset()
        {
        }

        private bool is_complete = false;
        public bool IsComplete
        {
            get
            {
                return this.is_complete;
            }

            private set
            {
                if (this.is_complete == value)
                    return;

                this.is_complete = value;
                this.CompleteStateChanged?.Invoke(this, EventArgs.Empty);
            }
        }

        public OperatorField Operator { get; private set; } = new OperatorField();
        private ProfileManager ProfileManager { get; set; }
        public string ArchiveMissingMessage { get; private set; }
    }
}
