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

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

        #region Contructors

        public Audittrail()
        {
            //_ConnNechatOtevrene = false;
        }
        public Audittrail(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 Audittrail(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}_Audittrail{2}", prefix, obdobi, typ);
        }

        public static DataTable GetDt()
        {
            DataTable dt = new DataTable();
            dt.TableName = "Audittrail";
            dt.Columns.Add("Radek", Type.GetType("System.Decimal"));
            dt.Columns.Add("Soubor", Type.GetType("System.String"));
            dt.Columns.Add("PK", Type.GetType("System.Decimal"));
            dt.Columns.Add("PorKont", Type.GetType("System.Decimal"));
            dt.Columns.Add("Datum_Cas", Type.GetType("System.DateTime"));
            dt.Columns.Add("RozdilCasu", Type.GetType("System.TimeSpan"));
            dt.Columns.Add("Akce", Type.GetType("System.String"));
            dt.Columns.Add("ID_Form", Type.GetType("System.Decimal"));
            dt.Columns.Add("Hodnota", Type.GetType("System.String"));
            dt.Columns.Add("Hodnota_puvodni", Type.GetType("System.String"));
            dt.Columns.Add("Field", Type.GetType("System.String"));
            dt.Columns.Add("Status", Type.GetType("System.String"));
            dt.Columns.Add("PricinaAkce", Type.GetType("System.String"));
            dt.Columns.Add("Poznamka", Type.GetType("System.String"));
            dt.Columns.Add("Paralelni_blok", Type.GetType("System.String"));
            dt.Columns.Add("Prikaz", Type.GetType("System.String"));
            dt.Columns.Add("Field_Cas", Type.GetType("System.TimeSpan"));

            // Dopočítávané hodnoty v oraclu po zpracování všech audittrailů
            // dt.Columns.Add("Poradi_zaznamu", Type.GetType("System.Decimal"))???
            // dt.Columns.Add("Zlom", Type.GetType("System.Decimal"))
            // dt.Columns.Add("Poradi_bloku", Type.GetType("System.Decimal"))
            // dt.Columns.Add("Poradi_ot_vRamici_porKont", Type.GetType("System.Decimal"))
            // dt.Columns.Add("Poradi_ot_vRamici_PK", Type.GetType("System.Decimal"))
            // dt.Columns.Add("Poradi_akce", Type.GetType("System.Decimal"))
            // dt.Columns.Add("ID_Akce_kontakt", Type.GetType("System.Decimal"))
            // dt.Columns.Add("Poradi_paginy", Type.GetType("System.Decimal"))
            return dt;
        }

        public void UlozData(string TabNazev, ref DataTable dt)
        {
            string OrSqlInsert = string.Format("INSERT INTO SETDOM.{0} " + "(Radek, Soubor, PK, PorKont, Datum_Cas, " + "RozdilCasu, Akce, ID_Form, Hodnota, Hodnota_puvodni, Field, Status, " + "PricinaAkce, Poznamka, Paralelni_blok, Prikaz, Field_Cas) " + "VALUES " + "(:pRadek, :pSoubor, :pPK, :pPorKont, :pDatum_Cas, " + ":pRozdilCasu, :pAkce, :pID_Form, :pHodnota, :pHodnota_puvodni, :pField, :pStatus, " + ":pPricinaAkce, :pPoznamka, :pParalelni_blok, :pPrikaz, :pField_Cas)", TabNazev);

            using (OracleDataAdapter da = new OracleDataAdapter())
            {
                da.InsertCommand = new OracleCommand();
                da.InsertCommand.CommandText = OrSqlInsert;
                da.InsertCommand.Connection = this.conn;
                da.InsertCommand.Parameters.Add(Audittrail.GetParametrSloupec_Radek());
                da.InsertCommand.Parameters.Add(Audittrail.GetParametrSloupec_Soubor());
                da.InsertCommand.Parameters.Add(Audittrail.GetParametrSloupec_PK());
                da.InsertCommand.Parameters.Add(Audittrail.GetParametrSloupec_PorKont());
                da.InsertCommand.Parameters.Add(Audittrail.GetParametrSloupec_Datum_Cas());
                da.InsertCommand.Parameters.Add(Audittrail.GetParametrSloupec_RozdilCasu());
                da.InsertCommand.Parameters.Add(Audittrail.GetParametrSloupec_Akce());
                da.InsertCommand.Parameters.Add(Audittrail.GetParametrSloupec_ID_Form());
                da.InsertCommand.Parameters.Add(Audittrail.GetParametrSloupec_Hodnota());
                da.InsertCommand.Parameters.Add(Audittrail.GetParametrSloupec_Hodnota_puvodni());
                da.InsertCommand.Parameters.Add(Audittrail.GetParametrSloupec_Field());
                da.InsertCommand.Parameters.Add(Audittrail.GetParametrSloupec_Status());
                da.InsertCommand.Parameters.Add(Audittrail.GetParametrSloupec_PricinaAkce());
                da.InsertCommand.Parameters.Add(Audittrail.GetParametrSloupec_Poznamka());
                da.InsertCommand.Parameters.Add(Audittrail.GetParametrSloupec_Paralelní_blok());
                da.InsertCommand.Parameters.Add(Audittrail.GetParametrSloupec_Prikaz());
                da.InsertCommand.Parameters.Add(Audittrail.GetParametrSloupec_Field_Cas());               

                da.Update(dt);

                /*if (!this.ConnNechatOtevrene)
                    this.conn.Close();*/
            }
        }

        #region Parametry Oracle

        #region Parametry Sloupcu
        public static OracleParameter GetParametrSloupec_Radek()
        {
            return new OracleParameter("pRadek", OracleDbType.Decimal, 0, "Radek");
        }
        public static OracleParameter GetParametrSloupec_Soubor()
        {
            return new OracleParameter("pSoubor", OracleDbType.Varchar2, 0, "Soubor");
        }
        public static OracleParameter GetParametrSloupec_Soubor(string Hodnota)
        {
            OracleParameter op = GetParametrSloupec_Soubor();
            op.Value = Hodnota;
            return op;
        }
        public static OracleParameter GetParametrSloupec_PK()
        {
            return new OracleParameter("pPK", OracleDbType.Decimal, 0, "PK");
        }
        public static OracleParameter GetParametrSloupec_PorKont()
        {
            return new OracleParameter("pPorKont", OracleDbType.Decimal, 0, "PorKont");
        }
        public static OracleParameter GetParametrSloupec_Datum_Cas()
        {
            return new OracleParameter("pDatum_Cas", OracleDbType.Date, 0, "Datum_Cas");
        }
        public static OracleParameter GetParametrSloupec_RozdilCasu()
        {
            return new OracleParameter("pRozdilCasu", OracleDbType.IntervalDS, 0, "RozdilCasu");
        }
        public static OracleParameter GetParametrSloupec_Akce()
        {
            return new OracleParameter("pAkce", OracleDbType.Varchar2, 0, "Akce");
        }
        public static OracleParameter GetParametrSloupec_ID_Form()
        {
            return new OracleParameter("pID_Form", OracleDbType.Decimal, 0, "ID_Form");
        }
        public static OracleParameter GetParametrSloupec_Hodnota()
        {
            return new OracleParameter("pHodnota", OracleDbType.NVarchar2, 0, "Hodnota");
        }
        public static OracleParameter GetParametrSloupec_Hodnota_puvodni()
        {
            return new OracleParameter("pHodnota_puvodni", OracleDbType.NVarchar2, 0, "Hodnota_puvodni");
        }
        public static OracleParameter GetParametrSloupec_Field()
        {
            return new OracleParameter("pField", OracleDbType.Varchar2, 0, "Field");
        }
        public static OracleParameter GetParametrSloupec_Status()
        {
            return new OracleParameter("pStatus", OracleDbType.Varchar2, 0, "Status");
        }
        public static OracleParameter GetParametrSloupec_PricinaAkce()
        {
            return new OracleParameter("pPricinaAkce", OracleDbType.Varchar2, 0, "PricinaAkce");
        }
        public static OracleParameter GetParametrSloupec_Poznamka()
        {
            return new OracleParameter("pPoznamka", OracleDbType.NVarchar2, 0, "Poznamka");
        }
        public static OracleParameter GetParametrSloupec_Paralelní_blok()
        {
            return new OracleParameter("pParalelni_blok", OracleDbType.NVarchar2, 0, "Paralelni_blok");
        }
        public static OracleParameter GetParametrSloupec_Prikaz()
        {
            return new OracleParameter("pPrikaz", OracleDbType.NVarchar2, 0, "Prikaz");
        }
        public static OracleParameter GetParametrSloupec_Field_Cas()
        {
            return new OracleParameter("pField_Casu", OracleDbType.IntervalDS, 0, "Field_Cas");
        }
        #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.Varchar2, 0, "");
            op.Value = kraj;
            return op;
        }

        #endregion
        #endregion


        public void VytvoritTabulku(string uloha, int rok, byte kvartal, RoleEnum PuvodDat)
        {
            string TabNazev = this.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.Audittrail_Vytvorit";
                cmd.Parameters.Add(this.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 soubor)
        {
            string TabNazev = this.TabulkaGetNazev(uloha, rok, kvartal, PuvodDat);
            this.SmazatData(TabNazev, soubor);
        }

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


    }
}
