using Oracle.ManagedDataAccess.Client;
using System;
using System.Data;
using System.IO;
using System.Text;
using System.Threading.Tasks;

namespace co_zpracování
{
    /// <summary>
    /// Hlavní úlohou této třídy je pouze oddědění Properties a metod všemi následujícími třídami: Audittrail, AudittrialChyba, Pagina, Kontakty
    /// </summary>
    class dbBase
    {
        private string _ConnStr;
        protected OracleConnection conn = new OracleConnection();

        private bool _ConnNechatOtevrene;

        public bool ConnNechatOtevrene
        {
            get { return _ConnNechatOtevrene; }
            set { _ConnNechatOtevrene = value; }
        }

        #region Constructors
        public dbBase()
        {
            _ConnNechatOtevrene = false;
        }
        public dbBase(string Id, string Psw)
        {
            this._ConnStr = string.Format("data Source=apolo.CSU;User Id={0}; Password={1};", Id, Psw);
            this.conn = new OracleConnection(_ConnStr);
            _ConnNechatOtevrene = false;
        }
        public dbBase(string Databaze, string Id, string Psw)
        {
            this._ConnStr = string.Format("data Source={0};User Id={1}; Password={2};", Databaze, Id, Psw);
            this.conn = new OracleConnection(_ConnStr);
            _ConnNechatOtevrene = false;
        }
        #endregion     

        /// <summary>
        /// Získává peridiocitu z tabulky
        /// </summary>
        /// <param name="uloha"></param>
        /// <param name="rok"></param>
        /// <param name="kvartal"></param>
        /// <returns></returns>
        public string GetPeriodicita(string uloha, int rok, byte kvartal)
        {
            string sql = "SELECT periodicita FROM setdom.uloha_obdobi uo join setdom.uloha u on uo.id_uloha=u.uloha_id where u.zkratka_ulohy= :uloha AND LOWER(obdobi) = :obdobi";
            OracleCommand oc = new OracleCommand(sql, conn);
            oc.Parameters.Add(new OracleParameter("uloha", uloha));
            oc.Parameters.Add(new OracleParameter("obdobi", $"{rok}q{kvartal}"));
            try
            {
                return oc.ExecuteScalar().ToString();
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// Nahrání pagin a kontaktů, paginy se nemažou ale aktualizují
        /// </summary>
        /// <param name="soubor">zde bude celá cesta včetně jména slo/slog/slogcr souboru</param>
        /// <param name="id"></param>
        /// <param name="password"></param>
        public static void ZpracujPaginy(string soubor, string id, string password)
        {
            Pagina orDbPagina = new Pagina(id, password);
            Kontakty orDbKontakt = new Kontakty(id, password);

            int Rok = Soubor.GetRok(soubor);
            byte Kvartal = Soubor.GetKvartal(soubor);
            string Uloha = Soubor.GetUloha(soubor);
            RoleEnum Role = Soubor.GetRole(soubor);

            Kraje Kraj = Soubor.GetKraj(soubor);
            string TazSoubor = Soubor.GetTazSoubor(soubor);

            string TabPaginaNazev = orDbPagina.TabulkaGetNazev(Uloha, Rok, Kvartal, Role);
            string TabKontaktNazev = orDbKontakt.TabulkaGetNazev(Uloha, Rok, Kvartal, Role);

            orDbPagina.VytvoritTabulku(TabPaginaNazev);
            orDbKontakt.VytvoritTabulku(TabKontaktNazev);

            switch (Role)
            {
                case RoleEnum.Tazatel:
                    orDbKontakt.SmazatData(TabKontaktNazev, TabPaginaNazev, TazSoubor);
                    break;
                case RoleEnum.Garant:
                    orDbKontakt.SmazatData(TabKontaktNazev, Kraj);
                    break;
                case RoleEnum.SprávceČR:
                    orDbKontakt.SmazatData(TabKontaktNazev);
                    break;
                default:
                    throw new Exception("Špatný původ souboru.");
            }

            string dbKontaktCesta = Path.Combine(soubor,"Kontakty.mdb");
            string connStr = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"{0}\";Jet OLEDB:Database Password=edsng1;", dbKontaktCesta);

            // Poznámka: Right(Poznamka,2000) - pokud je více znaků, pak nelze zapstat do Oraclu
            string sql = string.Format("SELECT VAL(IIF([Pagina]<9999,[Okres] & '0' & [Pagina], [Okres] & [Pagina])) AS PK, " + " CisBytu, CisObec, ID_VyslSetr, ID_VyslSetr_Pred, " + "Modul, NazObec, ObdZar, OsobniCislo, PocClenDom, PocDom, PosNav, " + "Right(Poznamka,2000) As Poznamka, RefRok, RefObd, SO, TazSoubor, Vlna, VyslHD1, VyslHD2 " + "FROM SETDOM.Pagina " + "WHERE Uloha='{0}';", Uloha);

            DataTable dtPagina = Pagina.GetDt();
            using(OracleDataAdapter da = new OracleDataAdapter(sql, connStr))
            {
                da.Fill(dtPagina);
            }

            using (OracleConnection ConnOra = new OracleConnection(GetConnStr(id, password)))
            {
                using(OracleCommand cmd = new OracleCommand("SETDOM.Pagina_UPSERT_P", ConnOra))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.Add("pNazevTabulky", OracleDbType.Varchar2);
                    cmd.Parameters[0].Value = TabPaginaNazev;
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_PK());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_CisBytu());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_CisObec());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_ID_VyslSetr());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_ID_VyslSetr_Pred());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_Modul());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_NazObec());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_ObdZar());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_OsobniCislo());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_PocClenDom());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_PocDom());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_PosNav());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_Poznamka());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_RefRok());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_RefObd());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_SO());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_TazSoubor());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_Vlna());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_VyslHD1());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_VyslHD2());

                    ConnOra.Open();

                    foreach (DataRow dr in dtPagina.Rows)
                    {
                        cmd.Parameters.Add("pNazevTabulky", OracleDbType.Varchar2);
                        cmd.Parameters[0].Value = TabPaginaNazev;
                        cmd.Parameters["pPK"].Value = dr["PK"].ToString();
                        cmd.Parameters["pCisBytu"].Value = dr["CisBytu"];
                        cmd.Parameters["pCisObec"].Value = dr["CisObec"];
                        cmd.Parameters["pID_VyslSetr"].Value = dr["ID_VyslSetr"];
                        cmd.Parameters["pID_VyslSetr_Pred"].Value = dr["ID_VyslSetr_Pred"];
                        cmd.Parameters["pModul"].Value = dr["Modul"];
                        cmd.Parameters["pNazObec"].Value = dr["NazObec"];
                        cmd.Parameters["pObdZar"].Value = dr["ObdZar"];
                        cmd.Parameters["pOsobniCislo"].Value = dr["OsobniCislo"];
                        cmd.Parameters["pPocClenDom"].Value = dr["PocClenDom"];
                        cmd.Parameters["pPocDom"].Value = dr["PocDom"];
                        cmd.Parameters["pPosNav"].Value = dr["PosNav"];
                        cmd.Parameters["pPoznamka"].Value = dr["Poznamka"];
                        cmd.Parameters["pRefRok"].Value = dr["RefRok"];
                        cmd.Parameters["pRefObd"].Value = dr["RefObd"];
                        cmd.Parameters["pSO"].Value = dr["SO"];
                        cmd.Parameters["pTazSoubor"].Value = dr["TazSoubor"];
                        cmd.Parameters["pVlna"].Value = dr["Vlna"];
                        cmd.Parameters["pVyslHD1"].Value = dr["VyslHD1"];
                        cmd.Parameters["pVyslHD2"].Value = dr["VyslHD2"];
                        cmd.ExecuteNonQuery();
                    }
                }

                ConnOra.Close();
            }

            // Nahrání kontaktů
            // Poznámka: Right(Poznamka,2000) - pokud je více znaků, pak nelze zapstat do Oraclu
            // Okres<>0: filtrují se všeobecné kontakty (obnova ze zálohy, synchonizace, apod.)

            sql = string.Format("SELECT VAL(IIF([Pagina]<9999,[Okres] & '0' & [Pagina], [Okres] & [Pagina])) AS PK, " + "PorKont, DatumOdSkutecne, DatumDoSkutecne, " + "DatumOdSystemove, DatumDoSystemove, DatumDalsiSchuzka, " + "ID_VyslSetr, ID_Akce, OsobniCislo, Right(Poznamka,2000) As Poznamka, " + "Dalkove, Zobrazit " + "FROM SETDOM.Kontakt " + "WHERE Uloha='{0}' And Okres<>0;", Uloha);

            DataTable dtKontakt = Kontakty.GetDt();

            using (OracleDataAdapter da = new OracleDataAdapter(sql, connStr))
            {
                da.Fill(dtKontakt);
            }

            foreach(DataRow dr in dtKontakt.Rows)
            {
                dr.SetAdded();
            }

            orDbKontakt.UlozData(TabKontaktNazev, ref dtKontakt);
            orDbPagina.ConnClose();
        }
        


        #region Connection

        public static string GetConnStr(string Databaze, string Id, string Psw)
        {
            return string.Format("Data Source={0};User Id={1};Password={2};", Databaze, Id, Psw);
        }

        public static string GetConnStr(string Id, string Psw)
        {
            return GetConnStr("apolo.CSU", Id, Psw);
        }


        public void ConnOpen()
        {
            if (this.conn.State == ConnectionState.Closed)
                this.conn.Open();
        }

        public void ConnClose()
        {
            if (this.conn.State == ConnectionState.Open)
                this.conn.Close();
        }

        #endregion
    }
}
