using System;
using System.Collections.Generic;
using System.Text;
using IndianHealthService.BMXNet.Model;
using System.Reflection;

namespace IndianHealthService.BMXNet.EHR.Model
{

    internal class CiaVisit : CiaObject, Visit
    {
        //Work around for incorrect encounter dll
        public static void InitialzeAccessToCSSEncounter()
        {
            Assembly encounter = Assembly.LoadFrom("Interop.CSS_Encounter.dll");
            if (encounter == null)
                return;

            foreach (Type each in encounter.GetExportedTypes())
            {
                if (each.Name.Equals("ICSS_Encounter"))
                {
                    LockedMethod = each.GetMethod("get_Locked");
                    PrepareMethod = each.GetMethod("Prepare");
                }
            }
        }

        public static MethodInfo LockedMethod = null;
        public static MethodInfo PrepareMethod = null;

        public static CiaVisit FindCurrent(CiaSession aSession)
        {
            if (aSession.CssEncounter.VisitStr == null)
            {
                return null;
            }
            else
            {
                CiaVisit answer = new CiaVisit();
                answer.CiaSession = aSession;
                return answer;
            }
        }

        private CiaSession _ciaSession = null;

        public CiaSession CiaSession
        {
            get { return _ciaSession; }
            set
            {
                _ciaSession = value;
                this.RefreshStateFromCssEncounter();
            }
        }


        protected void RefreshStateFromCssEncounter()
        {

            this.VisitString = this.CiaSession.CssEncounter.VisitStr;

            String[] peices = this.VisitString.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            this.Ien = (peices.Length == 4) ? peices[3] : null;

            this.DateTime = this.CiaSession.CssEncounter.DateTime;
            this.LocationName = this.CiaSession.CssEncounter.LocationName;
            this.ProviderName = this.CiaSession.CssEncounter.ProviderName;
            this.IsLocked = this.SafeLocked();
      
        }


        protected bool SafeLocked()
        {
            return LockedMethod == null ? false : this.RiskyLocked();
        }


        private bool RiskyLocked()
        {
            try
            {
                return (bool)LockedMethod.Invoke(this.CiaSession.CssEncounter, null);
            }
            catch
            {
                return false;
            }
        }

        private bool _isLocked = false;

        public bool IsLocked
        {
            get { return _isLocked; }
            set { _isLocked = value; }
        }

        private String _visitString = null;

        public String VisitString
        {
            get { return _visitString; }
            set { _visitString = value; }
        }

        private String _clinic = null;

        public String Clinic
        {
            get { return _clinic; }
            set { _clinic = value; }
        }
        private String _providerName;

        public String ProviderName
        {
            get { return _providerName; }
            set { _providerName = value; }
        }
        private String _locationName;

        public String LocationName
        {
            get { return _locationName; }
            set { _locationName = value; }
        }
        private DateTime _dateTime;

        public DateTime DateTime
        {
            get { return _dateTime; }
            set { _dateTime = value; }
        }

        public bool IsStub
        {
            get
            {
                if (this.Ien == null)
                {
                    this.RefreshStateFromCssEncounter();
                }
                return this.Ien == null;
            }
        }

        public bool IsFutureAppointment
        {
            get
            {
                return DateTime.Today < new DateTime(this.DateTime.Year, this.DateTime.Month, this.DateTime.Day);
            }
        }

        public bool Create()
        {
            return this.Create(true);
        }


        public bool Create(bool showGuiToCreate)
        {
            if (this.IsStub)
            {
                if (showGuiToCreate)
                {
                    this.RiskyPrepare();
                }
                else
                {
                    this.RiskyPrepareNoDialog();
                }
                 this.RefreshStateFromCssEncounter();
            }

            return !this.IsStub;
        }

        private bool RiskyPrepareNoDialog()
        {
            try
            {
                //We do not want reference to TxOptionFlags enum
                //ofAll = 0,
                //ofProvider = 1,
                //ofSuppress = 2,
                //ofNotLocked = 4,
                //ofValidateOnly = 8,
                //ofPromptOnInvalid = 16,
                //ofForceVisit = 32,
                //CSS_Encounter.TxOptionFlags flags =  CSS_Encounter.TxOptionFlags.ofForceVisit | CSS_Encounter.TxOptionFlags.ofNotLocked;
                int flags = 32 | 4;
                return (bool)PrepareMethod.Invoke(this.CiaSession.CssEncounter, new object[] { flags });
            }
            catch
            {
                return false;
            }
        }

        private bool RiskyPrepare()
        {
            try
            {
                //We do not want reference to TxOptionFlags enum
                //ofAll = 0,
                //ofProvider = 1,
                //ofSuppress = 2,
                //ofNotLocked = 4,
                //ofValidateOnly = 8,
                //ofPromptOnInvalid = 16,
                //ofForceVisit = 32,
                //CSS_Encounter.TxOptionFlags flags = CSS_Encounter.TxOptionFlags.ofPromptOnInvalid | CSS_Encounter.TxOptionFlags.ofForceVisit | CSS_Encounter.TxOptionFlags.ofNotLocked;
                int flags = 16 | 32 | 4;
                return (bool)PrepareMethod.Invoke(this.CiaSession.CssEncounter, new object[] { flags });
            }
            catch
            {
                return false;
            }
        }

        public override string ToString()
        {
            return this.Label;
        }

        public String Label
        {

            get { return this.DateTime.ToShortDateString() + " " + this.Clinic + ", " + this.ProviderName; }
        }
    }
}