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

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

        #region Contructors

        public Kontakty()
        {
            //_ConnNechatOtevrene = false;
        }
        public Kontakty(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 Kontakty(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

        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 půlroč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}_Kontakty{2}", prefix, obdobi, typ);
        }

        public static DataTable GetDt()
        {
            DataTable dt = new DataTable();
            dt.TableName = "Kontakt";
            dt.Columns.Add("PK", Type.GetType("System.Double"));
            dt.Columns.Add("PorKont", Type.GetType("System.Int16"));
            dt.Columns.Add("DatumOdSkutecne", Type.GetType("System.DateTime"));
            dt.Columns.Add("DatumDoSkutecne", Type.GetType("System.DateTime"));
            dt.Columns.Add("DatumDoSystemove", Type.GetType("System.DateTime"));
            dt.Columns.Add("DatumDalsiSchuzka", Type.GetType("System.DateTime"));
            dt.Columns.Add("ID_VyslSetr", Type.GetType("System.Byte"));
            dt.Columns.Add("ID_Akce", Type.GetType("System.Byte"));
            dt.Columns.Add("OsobniCislo", Type.GetType("System.Int32"));
            dt.Columns.Add("Poznamka", Type.GetType("System.String"));
            dt.Columns.Add("Dalkove", Type.GetType("System.Boolean"));
            dt.Columns.Add("Zobrazit", Type.GetType("System.Boolean"));
            return dt;
        }

        public void UlozData(string TabNazev, ref DataTable dt)
        {
            string OrSqlInsert = string.Format("INSERT INTO SETDOM.{0} " + "(PK, PorKont, DatumOdSkutecne, DatumDoSkutecne, DatumOdSystemove, " + "DatumDoSystemove, DatumDalsiSchuzka, ID_VyslSetr, ID_Akce, OsobniCislo, " + "Poznamka, Dalkove, Zobrazit) " + "VALUES " + "(:pPK, :pPorKont, :pDatumOdSkutecne, :pDatumDoSkutecne, :pDatumOdSystemove, " + ":pDatumDoSystemove, :pDatumDalsiSchuzka, :pID_VyslSetr, :pID_Akce, :pOsobniCislo, " + ":pPoznamka, :pDalkove, :pZobrazit)", TabNazev);

            using (OracleDataAdapter da = new OracleDataAdapter())
            {
                da.InsertCommand = new OracleCommand();
                da.InsertCommand.CommandText = OrSqlInsert; da.InsertCommand.Connection = this.conn;
                da.InsertCommand.Parameters.Add(Kontakty.GetParametrSloupec_PK());
                da.InsertCommand.Parameters.Add(Kontakty.GetParametrSloupec_PorKont());
                da.InsertCommand.Parameters.Add(Kontakty.GetParametrSloupec_DatumOdSkutecne());
                da.InsertCommand.Parameters.Add(Kontakty.GetParametrSloupec_DatumDoSkutecne());
                da.InsertCommand.Parameters.Add(Kontakty.GetParametrSloupec_DatumOdSystemove());
                da.InsertCommand.Parameters.Add(Kontakty.GetParametrSloupec_DatumDoSystemove());
                da.InsertCommand.Parameters.Add(Kontakty.GetParametrSloupec_DatumDalsiSchuzka());
                da.InsertCommand.Parameters.Add(Kontakty.GetParametrSloupec_ID_VyslSetr());
                da.InsertCommand.Parameters.Add(Kontakty.GetParametrSloupec_ID_Akce());
                da.InsertCommand.Parameters.Add(Kontakty.GetParametrSloupec_OsobniCislo());
                da.InsertCommand.Parameters.Add(Kontakty.GetParametrSloupec_Poznamka());
                da.InsertCommand.Parameters.Add(Kontakty.GetParametrSloupec_Dalkove());
                da.InsertCommand.Parameters.Add(Kontakty.GetParametrSloupec_Zobrazit());
                da.Update(dt);
            }
        }

        #region Parametry Oracle

        #region Parametry sloupců
        public static OracleParameter GetParametrSloupec_PK()
        {
            return new OracleParameter("pPK", OracleDbType.Double, 0, "PK");
        }
        public static OracleParameter GetParametrSloupec_PorKont()
        {
            return new OracleParameter("pPorKont", OracleDbType.Int16, 0, "PorKont");
        }
        public static OracleParameter GetParametrSloupec_DatumOdSkutecne()
        {
            return new OracleParameter("pDatumOdSkutecne", OracleDbType.Date, 0, "DatumOdSkutecne");
        }
        public static OracleParameter GetParametrSloupec_DatumDoSkutecne()
        {
            return new OracleParameter("pDatumDoSkutecne", OracleDbType.Date, 0, "DatumDoSkutecne");
        }
        public static OracleParameter GetParametrSloupec_DatumOdSystemove()
        {
            return new OracleParameter("pDatumOdSystemove", OracleDbType.Date, 0, "DatumOdSystemove");
        }
        public static OracleParameter GetParametrSloupec_DatumDoSystemove()
        {
            return new OracleParameter("pDatumDoSystemove", OracleDbType.Date, 0, "DatumDoSystemove");
        }
        public static OracleParameter GetParametrSloupec_DatumDalsiSchuzka()
        {
            return new OracleParameter("pDatumDalsiSchuzka", OracleDbType.Date, 0, "DatumDalsiSchuzka");
        }
        public static OracleParameter GetParametrSloupec_ID_VyslSetr()
        {
            return new OracleParameter("pID_VyslSetr", OracleDbType.Byte, 0, "ID_VyslSetr");
        }
        public static OracleParameter GetParametrSloupec_ID_Akce()
        {
            return new OracleParameter("pID_Akce", OracleDbType.Byte, 0, "ID_Akce");
        }
        public static OracleParameter GetParametrSloupec_OsobniCislo()
        {
            return new OracleParameter("pOsobniCislo", OracleDbType.Int32, 0, "OsobniCislo");
        }
        public static OracleParameter GetParametrSloupec_Poznamka()
        {
            return new OracleParameter("pPoznamka", OracleDbType.NVarchar2, 0, "Poznamka");
        }
        public static OracleParameter GetParametrSloupec_Dalkove()
        {
            return new OracleParameter("pDalkove", OracleDbType.Byte, 0, "Dalkove");
        }
        public static OracleParameter GetParametrSloupec_Zobrazit()
        {
            return new OracleParameter("pZobrazit", OracleDbType.Byte, 0, "Zobrazit");
        }
        #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 = Convert.ToByte(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.Kontakty_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 TabPaginaNazev, string TazSoubor)
        {
            string TabNazev = TabulkaGetNazev(uloha, rok, kvartal, PuvodDat);
            this.SmazatData(TabNazev, TabPaginaNazev, TazSoubor);
        }

        public void SmazatData(string TabNazev, string TabPaginaNazev,string TazSoubor)
        {
            using (OracleCommand cmd = new OracleCommand())
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = "SETDOM.Smazat_Kontakty_TazSoubor";
                OracleParameter opNazevTabulkyKontakty = new OracleParameter("NazevTabulkyKontakty", OracleDbType.Varchar2,0,"");
                opNazevTabulkyKontakty.Value = TabNazev;
                cmd.Parameters.Add(opNazevTabulkyKontakty);
                OracleParameter opNazevTabulkyPagina = new OracleParameter("NazevTabulkyPagina", OracleDbType.Varchar2, 0, "");
                opNazevTabulkyPagina.Value = TabPaginaNazev;
                cmd.Parameters.Add(opNazevTabulkyPagina);
                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_Kontakty_Kraj";
                cmd.Parameters.Add(this.GetParametr_NazevTab("SETDOM." + 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_Kontakty";
                cmd.Parameters.Add(this.GetParametr_NazevTab(TabNazev));
                cmd.Connection = this.conn;
                this.ConnOpen();
                cmd.ExecuteNonQuery();
                if (!ConnNechatOtevrene)
                    this.ConnClose();
            }
        }

        public DataTable VstupDoDotazniku1(string NazevTabulky)
        {
            string sql = string.Format("SELECT setdom.{0}.PK, setdom.{0}.PORKONT, setdom.{0}.DATUMODSYSTEMOVE " + "FROM setdom.{0} INNER JOIN setdom.ciselnik_vysledku ON setdom.{0}.ID_AKCE = ciselnik_vysledku.ID " + "WHERE ciselnik_vysledku.VSTUPDODOTAZNIKU = 1", NazevTabulky);
            DataTable dt = new DataTable();
            using (OracleCommand cmd = new OracleCommand(sql))
            {
                using (OracleDataAdapter da = new OracleDataAdapter(sql, this.conn))
                {
                    da.Fill(dt);
                }
            }

            //this.ConnClose();
            return dt;
        }
    }
}
