using Oracle.ManagedDataAccess.Client;
using System;
using System.Data;

namespace co_zpracování
{
    class Pagina : dbBase
    {
        private string _ConnStr;
        //private bool _ConnNechatOtevrene;

        #region Contructors

        public Pagina()
        {
            //_ConnNechatOtevrene = false;
        }
        public Pagina(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 Pagina(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>
        /// Bere si platný název tabulky podle dat v Oracle.
        /// </summary>
        /// <param name="uloha"></param>
        /// <param name="rok"></param>
        /// <param name="kvartal"></param>
        /// <param name="PuvodDat"></param>
        /// <returns></returns>
        public string TabulkaGetNazev(string uloha, int rok, byte kvartal, RoleEnum PuvodDat)
        {
            string typ = "";
            DateTime rokObdobi = new DateTime(rok, 1, 1);
            string obdobi = rokObdobi.ToString("yy");


            // Nastavení platného prefixu podle databáze
            string sql = "Select prefix_ulohy from setdom.uloha where zkratka_ulohy=:uloha";
            OracleCommand oc = new OracleCommand(sql, conn);
            oc.Parameters.Add(new OracleParameter("uloha", uloha));

            string prefix = oc.ExecuteScalar().ToString();

            if (prefix == null)
            {
                throw new Exception("Úloha není založena v Oraclu");
            }

            oc.Parameters.Clear();

            // Vybírám podle periodicity, zda do názvu uvést i kvartál
            string periodicita = GetPeriodicita(uloha, rok, kvartal);

            if (periodicita == null)    // Pokud nenajdeme období
            {
                // Hledat v jiném období
                switch (kvartal)
                {
                    case 1:
                        throw new Exception($"Pro úlohu {uloha} není založeno obdobi {rok}q{kvartal} v Oraclu");
                    case 2:
                        periodicita = GetPeriodicita(uloha, rok, 1);
                        if (periodicita == "q")
                        {
                            obdobi += 1;
                            break;
                        }
                        else if (periodicita == "p")
                        {
                            obdobi += 1;
                            break;
                        }
                        else if (periodicita == "r")
                        {
                            // Roční peridiocita, období zůstává bez přidaného kvartálu
                            break;
                        }
                        else
                        {
                            throw new Exception($"Pro úlohu {uloha} není založeno obdobi {rok}q{kvartal} v Oraclu");
                        }
                    case 3:
                        periodicita = GetPeriodicita(uloha, rok, 1);
                        if (periodicita == "r")
                        {
                            // Roční periodicita, období zůstává bez přidaného kvartálu
                            break;
                        }
                        else
                        {
                            throw new Exception($"Pro úlohu {uloha} není založeno obdobi {rok}q{kvartal} v Oraclu");
                        }
                    case 4:
                        periodicita = GetPeriodicita(uloha, rok, 3); // Kontroluji ještě q3
                        if (periodicita == null)
                        {
                            periodicita = GetPeriodicita(uloha, rok, 1);
                            if (periodicita == "r")  // q1 může být v tomto případě pouze roční peridiocita
                            {
                                // q1 je v tomto případě roční období, nepřidává se tedy kvartál
                                break;
                            }
                            else
                            {
                                throw new Exception($"Pro úlohu {uloha} není založeno obdobi {rok}q{kvartal} v Oraclu");
                            }
                        }
                        else
                        {
                            if (periodicita == "p")  // q3 může být v tomto případě pouze půlroční peridiocita
                            {
                                obdobi += 3;
                                break;
                            }
                            else
                            {
                                throw new Exception($"Pro úlohu {uloha} není založeno obdobi {rok}q{kvartal} v Oraclu");
                            }
                        }
                    default:
                        break;
                }

            }
            else if (periodicita == "q")
            {
                obdobi += kvartal;
            }
            else if (periodicita == "p")
            {
                obdobi += kvartal;
            }
            else if (periodicita == "r")
            {
                // Roční období, období  zůstává bez přidaného kvartálu
            }

            switch (PuvodDat)
            {
                case RoleEnum.Tazatel:
                    typ = "_T";
                    break;
                case RoleEnum.Garant:
                    typ = "_G";
                    break;
                case RoleEnum.SprávceČR:
                    typ = "";
                    break;
                default:
                    throw new ArgumentException("Špatný původ souboru.");
            }


            return string.Format("{0}{1}_Pagina{2}", prefix, obdobi, typ);
        }

        public static DataTable GetDt()
        {
            DataTable dt = new DataTable();
            dt.TableName = "Pagina";
            dt.Columns.Add("PK", Type.GetType("System.Double"));
            dt.Columns.Add("CisBytu", Type.GetType("System.Byte"));
            dt.Columns.Add("CisObec", Type.GetType("System.Int32"));
            dt.Columns.Add("ID_VyslSetr", Type.GetType("System.Byte"));
            dt.Columns.Add("ID_VyslSetr_Pred", Type.GetType("System.Byte"));
            dt.Columns.Add("Modul", Type.GetType("System.String"));
            dt.Columns.Add("NazObec", Type.GetType("System.String"));
            dt.Columns.Add("ObdZar", Type.GetType("System.Int16"));
            dt.Columns.Add("OsobniCislo", Type.GetType("System.Int32"));
            dt.Columns.Add("PocClenDom", Type.GetType("System.String"));
            dt.Columns.Add("PocDom", Type.GetType("System.Byte"));
            dt.Columns.Add("PosNav", Type.GetType("System.DateTime"));
            dt.Columns.Add("Poznamka", Type.GetType("System.String"));
            dt.Columns.Add("RefRok", Type.GetType("System.Int16"));
            dt.Columns.Add("RefObd", Type.GetType("System.Int16"));
            dt.Columns.Add("SO", Type.GetType("System.Int16"));
            dt.Columns.Add("TazSoubor", Type.GetType("System.String"));
            dt.Columns.Add("Vlna", Type.GetType("System.Byte"));
            dt.Columns.Add("VyslHD1", Type.GetType("System.Byte"));
            dt.Columns.Add("VyslHD2", Type.GetType("System.Byte"));
            return dt;
        }

        public void UlozData(string TabNazev, ref DataTable dt)
        {
            string OrSqlInsert = string.Format(("INSERT INTO SETDOM.{0} " + ("(PK, CisBytu, CisObec, ID_VyslSetr, ID_VyslSetr_Pred, " + ("Modul, NazObec, ObdZar, OsobniCislo, PocClenDom, PocDom, PosNav, " + ("Poznamka, RefRok, RefObd, SO, TazSoubor, Vlna, VyslHD1, VyslHD2) " + ("VALUES " + ("(:pPK, :pCisBytu, :pCisObec, :pID_VyslSetr, :pID_VyslSetr_Pred, " + (":pModul, :pNazObec, :pObdZar, :pOsobniCislo, :pPocClenDom, :pPocDom, :pPosNav, " + ":pPoznamka, :pRefRok, :pRefObd, :pSO, :pTazSoubor, :pVlna, :pVyslHD1, :pVyslHD2)"))))))), TabNazev);
            using (OracleDataAdapter da = new OracleDataAdapter())
            {
                da.InsertCommand = new OracleCommand();
                da.InsertCommand.CommandText = OrSqlInsert;
                da.InsertCommand.Connection = this.conn;
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_PK());
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_CisBytu());
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_CisObec());
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_ID_VyslSetr());
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_ID_VyslSetr_Pred());
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_Modul());
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_NazObec());
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_ObdZar());
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_OsobniCislo());
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_PocClenDom());
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_PocDom());
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_PosNav());
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_Poznamka());
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_RefRok());
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_RefObd());
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_SO());
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_TazSoubor());
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_Vlna());
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_VyslHD1());
                da.InsertCommand.Parameters.Add(Pagina.GetParametrSloupec_VyslHD2());
                da.Update(dt); 
            }
        }

        #region Parametry Oracle

        #region Parametry Sloupců
        public static OracleParameter GetParametrSloupec_PK()
        {
            return new OracleParameter("pPK", OracleDbType.NVarchar2, 0, "PK");
        }

        public static OracleParameter GetParametrSloupec_CisBytu()
        {
            return new OracleParameter("pCisBytu", OracleDbType.Byte, 0, "CisBytu");
        }

        public static OracleParameter GetParametrSloupec_CisObec()
        {
            return new OracleParameter("pCisObec", OracleDbType.Int32, 0, "CisObec");
        }
        public static OracleParameter GetParametrSloupec_ID_VyslSetr()
        {
            return new OracleParameter("pID_VyslSetr", OracleDbType.Byte, 0, "ID_VyslSetr");
        }
        public static OracleParameter GetParametrSloupec_ID_VyslSetr_Pred()
        {
            return new OracleParameter("pID_VyslSetr_Pred", OracleDbType.Byte, 0, "ID_VyslSetr_Pred");
        }
        public static OracleParameter GetParametrSloupec_Modul()
        {
            return new OracleParameter("pModul", OracleDbType.NVarchar2, 0, "Modul");
        }
        public static OracleParameter GetParametrSloupec_NazObec()
        {
            return new OracleParameter("pNazObec", OracleDbType.NVarchar2, 0, "NazObec");
        }
        public static OracleParameter GetParametrSloupec_ObdZar()
        {
            return new OracleParameter("pObdZar", OracleDbType.Int16, 0, "ObdZar");
        }
        public static OracleParameter GetParametrSloupec_OsobniCislo()
        {
            return new OracleParameter("pOsobniCislo", OracleDbType.Int32, 0, "OsobniCislo");
        }
        public static OracleParameter GetParametrSloupec_PocClenDom()
        {
            return new OracleParameter("pPocClenDom", OracleDbType.Varchar2, 0, "PocClenDom");
        }
        public static OracleParameter GetParametrSloupec_PocDom()
        {
            return new OracleParameter("pPocDom", OracleDbType.Byte, 0, "PocDom");
        }
        public static OracleParameter GetParametrSloupec_PosNav()
        {
            return new OracleParameter("pPosNav", OracleDbType.Date, 0, "PosNav");
        }
        public static OracleParameter GetParametrSloupec_Poznamka()
        {
            return new OracleParameter("pPoznamka", OracleDbType.NVarchar2, 0, "Poznamka");
        }
        public static OracleParameter GetParametrSloupec_RefRok()
        {
            return new OracleParameter("pRefRok", OracleDbType.Int16, 0, "RefRok");
        }
        public static OracleParameter GetParametrSloupec_RefObd()
        {
            return new OracleParameter("pRefObd", OracleDbType.Int16, 0, "RefObd");
        }
        public static OracleParameter GetParametrSloupec_SO()
        {
            return new OracleParameter("pSO", OracleDbType.Int16, 0, "SO");
        }
        public static OracleParameter GetParametrSloupec_TazSoubor()
        {
            return new OracleParameter("pTazSoubor", OracleDbType.Varchar2, 0, "TazSoubor");
        }

        public static OracleParameter GetParametrSloupec_TazSoubor(string Hodnota)
        {
            OracleParameter op = GetParametrSloupec_TazSoubor();
            op.Value = Hodnota;
            return op;
        }

        public static OracleParameter GetParametrSloupec_Vlna()
        {
            return new OracleParameter("pVlna", OracleDbType.Byte, 0, "Vlna");
        }

        public static OracleParameter GetParametrSloupec_VyslHD1()
        {
            return new OracleParameter("pVyslHD1", OracleDbType.Byte, 0, "VyslHD1");
        }

        public static OracleParameter GetParametrSloupec_VyslHD2()
        {
            return new OracleParameter("pVyslHD2", OracleDbType.Byte, 0, "VyslHD2");
        }

        #endregion

        #region Parametry Ostatní

        private OracleParameter GetParametr_NazevTab(string TabNazev)
        {
            OracleParameter op = new OracleParameter("NazevTabulky",OracleDbType.Varchar2,0,"");
            op.Value = TabNazev;
            return op;
        }       
        
        private OracleParameter GetParametr_Kraj(Kraje kraj)
        {
            OracleParameter op = new OracleParameter("kraj",OracleDbType.Byte,0,"");
            op.Value = kraj;
            return op;
        }

        #endregion

        #endregion

        public void VytvoritTabulku(string uloha, int rok, byte kvartal, RoleEnum PuvodDat)
        {
            string TabNazev = TabulkaGetNazev(uloha, rok, kvartal, PuvodDat);
            this.VytvoritTabulku(TabNazev);
        }

        public void VytvoritTabulku(string TabNazev)
        {
            using (OracleCommand cmd = new OracleCommand())
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = "SETDOM.Pagina_Vytvorit";
                cmd.Parameters.Add(GetParametr_NazevTab(TabNazev));
                cmd.Connection = this.conn;
                this.ConnOpen();
                cmd.ExecuteNonQuery();
                if (!ConnNechatOtevrene)
                    this.ConnClose();
            }
        }

        public void SmazatData(string uloha, int rok, byte kvartal, RoleEnum PuvodDat, string TazSoubor)
        {
            string TabNazev = TabulkaGetNazev(uloha,rok,kvartal,PuvodDat);
            this.SmazatData(TabNazev, TazSoubor);
        }

        public void SmazatData(string TabNazev, string TazSoubor)
        {
            using(OracleCommand cmd = new OracleCommand())
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = "SETDOM.Smazat_Pagina_TazSoubor";
                cmd.Parameters.Add(this.GetParametr_NazevTab(TabNazev));
                cmd.Parameters.Add(Pagina.GetParametrSloupec_TazSoubor(TazSoubor));
                cmd.Connection = this.conn;
                this.ConnOpen();
                cmd.ExecuteNonQuery();
                if (!ConnNechatOtevrene)
                    this.ConnClose();
            }
        }

        public void SmazatData(string uloha, int rok, byte kvartal, RoleEnum PuvodDat, Kraje kraj)
        {
            string TabNazev = TabulkaGetNazev(uloha, rok, kvartal, PuvodDat);
            this.SmazatData(TabNazev, kraj);
        }

        public void SmazatData(string TabNazev, Kraje kraj)
        {
            using(OracleCommand cmd = new OracleCommand())
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = "SETDOM.Smazat_Pagina_Kraj";
                cmd.Parameters.Add(this.GetParametr_NazevTab(TabNazev));
                cmd.Parameters.Add(this.GetParametr_Kraj(kraj));
                cmd.Connection = this.conn;
                this.ConnOpen();
                cmd.ExecuteNonQuery();
                if(!ConnNechatOtevrene)
                    this.ConnClose();
            }
        }

        public void SmazatData(string uloha, int rok, byte kvartal, RoleEnum PuvodDat)
        {
            string TabNazev = TabulkaGetNazev(uloha,rok,kvartal,PuvodDat);
            this.SmazatData(TabNazev);
        }

        public void SmazatData(string TabNazev)
        {
            using (OracleCommand cmd = new OracleCommand())
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = "SETDOM.Smazat_Pagina";
                cmd.Parameters.Add(this.GetParametr_NazevTab(TabNazev));
                cmd.Connection = this.conn;
                this.ConnOpen();
                cmd.ExecuteNonQuery();
                if (!ConnNechatOtevrene)
                    this.ConnClose();
            }
        }
    }
}
