// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2024, 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 System.Collections.Generic;
using Hiperscan.AnalysisModule;
using System.Linq;
using Hiperscan.AnalysisModule.Quantification;

namespace Hiperscan.ApoIdentCore.SectionManager.Result
{
    public class CannabisResult : PlsResultSet
    {
        public const string CBD_ID = "PLS_001";
        public const string THC_ID = "PLS_002";

        public const double MAX_THC = 35d;
        public const double MAX_CBD = 20d;

        public const double BALANCED_TYPE_MAX_CONTENT = 15d;
        public const double BALANCED_TYPE_MIN_CONTENT = 3d;

        public const double CBD_TYPE_MIN_CBD = 4d;
        public const double THC_TYPE_MIN_THC = 5d;

        public CannabisResult(PlsResultSet result, List<IdentSample> content_resolver)
        {
            this.Identifier = result.Identifier;
            this.Absorbance = result.Absorbance;
            this.AnalysisMethodeVersion = result.AnalysisMethodeVersion;
            this.Date = result.Date;
            this.Contents = result.Contents;
            this.Samples = content_resolver;
        }

        public string GetCannabisClassification()
        {
            if (false == this.IsTrustable)
                return Catalog.GetString("Implausible result");

            if (this.RawTHCResult >= CannabisResult.THC_TYPE_MIN_THC && this.RawTHCResult <= CannabisResult.MAX_THC
             && this.RawCBDResult <  CannabisResult.BALANCED_TYPE_MIN_CONTENT)
                return Catalog.GetString("THC-dominant type");
            if (this.RawTHCResult >= CannabisResult.BALANCED_TYPE_MIN_CONTENT && this.RawTHCResult <= CannabisResult.BALANCED_TYPE_MAX_CONTENT
             && this.RawCBDResult >= CannabisResult.BALANCED_TYPE_MIN_CONTENT && this.RawCBDResult <= CannabisResult.BALANCED_TYPE_MAX_CONTENT)
                return Catalog.GetString("THC/CBD-intermediate type");
            if (this.RawTHCResult <  CannabisResult.BALANCED_TYPE_MIN_CONTENT
             && this.RawCBDResult >= CannabisResult.CBD_TYPE_MIN_CBD && this.RawCBDResult <= CannabisResult.MAX_CBD)
                return Catalog.GetString("CBD-dominant type");
            // e.g. <5% THC, <3% CBD -SIB 2024-06-17
            return Catalog.GetString("no defined type");
        }

        public string GetCBDTolerance()
        {
            return String.Format("±\u202F{0:f1}%", 2.2);
        }

        public string GetTHCTolerance()
        {
            return String.Format("±\u202F{0:f1}%", 5.8);
        }

        public string GetCBDSigma(bool as_text = false)
        {
            return this.GetSigma(as_text, 2);
        }

        public string GetTHCSigma(bool as_text = false)
        {
            return this.GetSigma(as_text, 2);
        }

        private string GetSigma(bool as_text, int number_of_sigma)
        {
            string out_put = String.Empty;

            if (as_text)
                out_put = $"({number_of_sigma} Sigma)";
            else
                out_put = $"({number_of_sigma}σ)";

            return out_put;
        }

        public string GetTHCResultInPercent()
        {
            return this.RawTHCResult.ToString("f1") + "%";
        }

        public string GetCBDResultInPercent()
        {
            return this.RawCBDResult.ToString("f1") + "%";
        }

        public double RawCBDResult
        {
            get
            {
                return this.GetContent(CannabisResult.CBD_ID);
            }
        }

        public double RawTHCResult
        {
            get
            {
                return this.GetContent(CannabisResult.THC_ID);
            }
        }

        private double GetContent(string id)
        {
            string index = this.Samples.Where(s => s.Id == id).
                               First().Info;

            return this.Contents[index];
        }

        public static CannabisResult GetTestInstance()
        {
            PlsResultSet result = new PlsResultSet();
            result.Identifier = "Cannabis";
            result.Contents.Add(Catalog.GetString("THC"), 8.6);
            result.Contents.Add(Catalog.GetString("CBD"), 2.1);

            List<IdentSample> samples = new List<IdentSample>();
            IdentSample sample = new IdentSample();
            sample.Id = CannabisResult.THC_ID;
            sample.Info = Catalog.GetString("THC");
            samples.Add(sample);

            sample = new IdentSample();
            sample.Id = CannabisResult.CBD_ID;
            sample.Info = Catalog.GetString("CBD");
            samples.Add(sample);

            return new CannabisResult(result, samples);
        }

        public bool IsTrustable
        {
            get
            {
                if (this.RawTHCResult > CannabisResult.MAX_THC)
                    return false;

                if (this.RawCBDResult > CannabisResult.MAX_CBD)
                    return false;

                return true;
            }
        }

        private List<IdentSample> Samples { get; set; }
    }
}
