using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using Baza_Reklam.Classes.Model;
using Baza_Reklam.REKLAMADataSetTableAdapters;

namespace Baza_Reklam.Classes.Helpers
{
    public class FakturaHelper
    {
        public enum PaymentType
        {
            Card = 0,
            Transfer = 1,
            Cash = 2,
            Barter = 3
        }

        public enum ClientId
        {
            Katowice = 678,
            Poznan = 18845
        }

        public enum OfficeId
        {
            Redakcja = 2,
            Katowice = 4,
            Poznan = 6
        }

        public enum OrderId
        {
            Poznan = 272,
            Katowice = 273
        }

        public enum BankAccount
        {
            CentralaPln = 43
        }

        public static string GetPaymentType(int paymentType)
        {
            switch (paymentType)
            {
                case 0:
                    return "Karta kredytowa";
                case 1:
                    return "Przelew";
                case 2:
                    return "Gotówka";
                case 3:
                    return "Barter";
                default:
                    return string.Empty;
            }
        }

        public static bool AddInvoice(REKLAMADataSet reklamaDataSet, FAKTURYTableAdapter fakturaAdapter,
                                      FAKTURA_DETAILSTableAdapter fakturaDetailsAdapter,
                                      WplatyTableAdapter wplataAdapter, REKLAMADataSet.FAKTURYRow fakturaRow)
        {
            SqlConnection conn;
            SqlTransaction transaction = null;
            try
            {
                conn = new SqlConnection(ConnString.getConnString().Value);
                fakturaAdapter.Connection = conn;
                fakturaDetailsAdapter.Connection = conn;
                wplataAdapter.Connection = conn;

                conn.Open();

                transaction = conn.BeginTransaction();
                fakturaAdapter.AttachTransaction(transaction);
                fakturaDetailsAdapter.AttachTransaction(transaction);
                wplataAdapter.AttachTransaction(transaction);

                fakturaAdapter.Update(reklamaDataSet.FAKTURY);
                fakturaDetailsAdapter.Update(reklamaDataSet.FAKTURA_DETAILS);
                wplataAdapter.Update(reklamaDataSet.Wplaty);
                transaction.Commit();
            }
            catch (Exception)
            {
                if (transaction != null) transaction.Rollback();
                reklamaDataSet.FAKTURY.RemoveFAKTURYRow(fakturaRow);
                throw;
            }
            return true;
        }

        public static void AddInvoiceDetails(REKLAMADataSet.FAKTURYRow newInvoice,
                                             REKLAMADataSet.FAKTURYRow clientInvoice,
                                             REKLAMADataSet.FAKTURA_DETAILSRow detailsRow,
                                             REKLAMADataSet.FAKTURA_DETAILSDataTable detailsTable)
        {
            REKLAMADataSet.FAKTURA_DETAILSRow row = detailsTable.NewFAKTURA_DETAILSRow();

            row.ROK = detailsRow.ROK;
            row.MIESIAC = detailsRow.MIESIAC;
            row.TYTUL = detailsRow.TYTUL;
            row.NAZWA_USLUGI = clientInvoice != null
                                   ? clientInvoice.NUMER + "/" + clientInvoice.NUMER_ROZ + "/" + clientInvoice.NUMER_ROK +
                                     " | " + detailsRow.NAZWA_USLUGI
                                   : "";
            row.reklamaId = detailsRow.reklamaId;
            row.NR_WYDANIA = detailsRow.NR_WYDANIA;

            row.CENA_JEDN = detailsRow.CENA_JEDN;
            row.ILOSC = 1;
            row.JM = "szt.";

            row.UPUST_NETTO = detailsRow.UPUST_NETTO;
            row.UPUST_PR = detailsRow.UPUST_PR;
            row.NETTO = detailsRow.NETTO;
            row.S_VAT = VatHelper.PL22;
            row.VAT = (decimal)VatHelper.PL22 * detailsRow.NETTO;
            row.BRUTTO = detailsRow.NETTO * (decimal)(1 + VatHelper.PL22);

            row.TYP = 2;
            row.PODTYP = 1;
            row.ID_FAKTURY = newInvoice.ID_FAKTURY;

            row.wyroznienie = (!detailsRow.IswyroznienieNull() && detailsRow.wyroznienie);

            detailsTable.AddFAKTURA_DETAILSRow(row);
        }

        public static string GetNazwaUslugiPozKat(REKLAMADataSet.FAKTURYRow faktura,
                                                  REKLAMADataSet.FAKTURA_DETAILSRow pozycjaFaktury)
        {
            if (faktura == null) return string.Empty;

            return faktura.NUMER + "/" + faktura.NUMER_ROZ + "/" + faktura.NUMER_ROK + " | " +
                   pozycjaFaktury.NAZWA_USLUGI;
        }

        public static REKLAMADataSet.FAKTURYRow GetInvoice(DataTable fakturyTable,
                                                           REKLAMADataSet.KLIENCIRow klientAgencja,
                                                           SLOWNIKDataSet.AGENCJERow agencja,
                                                           SLOWNIKDataSet.AGENCJERow redakcja,
                                                           SLOWNIKDataSet.KONTARow bankAccount,
                                                           string numerRoz,
                                                           PaymentType paymentType,
                                                           DateTime dateTime)
        {
            REKLAMADataSet.FAKTURYRow naglowekFaktury = (REKLAMADataSet.FAKTURYRow)fakturyTable.NewRow();

            naglowekFaktury.KOREKTA = false;
            naglowekFaktury.NUMER_ROZ = numerRoz;
            naglowekFaktury.NUMER = DbUtils.numerNowejFaktury(naglowekFaktury.NUMER_ROZ, DateTime.Today.Year);
            naglowekFaktury.NUMER_ROK = DateTime.Today.Year;

            naglowekFaktury.DATA_WYSTAWIENIA = dateTime != DateTime.Today ? dateTime : DateTime.Today;

            naglowekFaktury.idZamowienia = agencja.Id_agencji == (int)OfficeId.Poznan
                                               ?
                                                   (int)OrderId.Poznan
                                               : (int)OrderId.Katowice;

            naglowekFaktury.ID_SPRZEDAWCY = agencja.Id_agencji;

            naglowekFaktury.EKSPORT = false;

            naglowekFaktury.MIEJSCOWOSC_WYSTAWIENIA = redakcja.miasto;
            naglowekFaktury.SPRZEDAWCA_ADRES = redakcja.Adres_Fk;
            naglowekFaktury.SPRZEDAWCA_NIP = redakcja.NIP;

            naglowekFaktury.PODPIS_WYSTAWIL = string.Empty;
            naglowekFaktury.DATA_SPRZEDAZY = naglowekFaktury.DATA_WYSTAWIENIA;

            naglowekFaktury.ID_NABYWCY = klientAgencja.CustomerID;
            naglowekFaktury.NABYWCA_ADRES = klientAgencja.Adres_Fkatura;
            naglowekFaktury.NABYWCA_NIP = klientAgencja.Nip;
            naglowekFaktury.opis = string.Empty;

            naglowekFaktury.SPOSOB_ZAPLATY = GetPaymentType((int)paymentType);

            naglowekFaktury.TERMIN_ZAPLATY = naglowekFaktury.DATA_SPRZEDAZY.AddDays(14);
            naglowekFaktury.ZAPLACONO = false;

            naglowekFaktury.FAKTURA_TYP = 2;
            naglowekFaktury.FAKTURA_PODTYP = 1;

            naglowekFaktury.ID_KONTA = Convert.ToInt16(bankAccount.id);

            naglowekFaktury.EndEdit();
            return naglowekFaktury;
        }

        public static bool IsSumaEmisjiMniejszaOdFakturyNetto(REKLAMADataSet.VIEW_ZESTAWIENIE_FAKTUR_NOWERow faktura)
        {
            if (faktura.IssumaNettoZEmisjiNull()) return false;

            if (IsFakturaWWalucie(faktura) && !faktura.Iswaluta_kursNull())
                return Math.Round(faktura.sumaNettoZEmisji / faktura.waluta_kurs, 0) <
                       (decimal)Math.Round(faktura.waluta_brutto, 0);

            return Math.Round(faktura.sumaNettoZEmisji, 0) < Math.Round(faktura.NETTO, 0);
        }

        public static bool IsFakturaWWalucie(REKLAMADataSet.VIEW_ZESTAWIENIE_FAKTUR_NOWERow faktura)
        {
            if (faktura.Iswaluta_mianoNull()) return false;
            if (string.IsNullOrEmpty(faktura.waluta_miano)) return false;
            if (faktura.waluta_miano.ToUpper() == "PLN") return false;

            return true;
        }


        public static List<Invoice> GetInvoiceList(int parentInvoiceId)
        {
            List<Invoice> invoices = new List<Invoice>();
            SqlConnection conn = null;
            SqlCommand cmd = null;
            SqlDataReader reader = null;

            const string query = "SELECT IDPozKat AS Id, NrFakturyPozKat AS Label, NettoPozKat AS Amount, DataWystawieniaPozKat AS Date FROM dbo.FakturyPoznanKatowice WHERE ID=@id";

            try
            {
                conn = new SqlConnection(ConnString.getConnString().Value);
                conn.Open();
                cmd = new SqlCommand(query, conn);
                cmd.Parameters.AddWithValue("@id", parentInvoiceId);
                reader = cmd.ExecuteReader();

                if (reader != null)
                    while (reader.Read())
                    {
                        Invoice invoice = new Invoice();
                        invoice.Id = Convert.ToInt32(reader["Id"]);
                        invoice.Label = Convert.ToString(reader["Label"]);
                        invoice.Amount = Convert.ToDecimal(reader["Amount"]);
                        invoice.Date = Convert.ToDateTime(reader["Date"]);
                        invoices.Add(invoice);
                    }
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                    reader.Dispose();
                }
                if (cmd != null)
                {
                    cmd.Dispose();
                }
                if (conn != null)
                {
                    conn.Close();
                    conn.Dispose();
                }
            }

            return invoices;
        }

        public static List<Invoice> GetPartnerInvoiceList(int year, int month, string partner)
        {
            List<Invoice> invoices = new List<Invoice>();
            SqlConnection conn = null;
            SqlCommand cmd = null;
            SqlDataReader reader = null;

            try
            {
                conn = new SqlConnection(ConnString.getConnString().Value);
                conn.Open();
                cmd = new SqlCommand("sp_FindPartnerInvoices", conn);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@year", year);
                cmd.Parameters.AddWithValue("@month", month);
                cmd.Parameters.AddWithValue("@partner", partner);
                reader = cmd.ExecuteReader();

                if (reader != null)
                    while (reader.Read())
                    {
                        Invoice invoice = new Invoice();
                        invoice.Id = Convert.ToInt32(reader["Id"]);
                        invoice.Label = Convert.ToString(reader["Number"]) + "/" + Convert.ToString(reader["AgentShortCut"]) + "/" + Convert.ToString(reader["Year"]);
                        invoice.Amount = Convert.ToDecimal(reader["Amount"]);
                        invoice.Date = Convert.ToDateTime(reader["Date"]);
                        invoice.PaidAmount = Convert.ToDecimal(reader["TotalPaid"]);
                        invoice.IsCorrectionInvoice = Convert.ToBoolean(reader["Correction"]);
                        invoice.Currency = Convert.ToString(reader["Currency"]);
                        invoice.WeekNumber = Convert.ToInt32(reader["WeekNumber"]);
                        invoices.Add(invoice);
                    }
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                    reader.Dispose();
                }
                if (cmd != null)
                {
                    cmd.Dispose();
                }
                if (conn != null)
                {
                    conn.Close();
                    conn.Dispose();
                }
            }

            return invoices;
        }

        /// <summary>
        /// Zwraca numer następnej faktury korekty dla danego agenta.
        /// </summary>
        public static int GetNewCorrectionInvoiceNumber(int year, int systemKsiegowy)
        {
            string query = "SELECT MAX(Numer) FROM Faktury WHERE Korekta=1 AND [Numer_Rok]=" + year + " AND SystemKsiegowyId=" + systemKsiegowy;

            object nr = DbUtils.ExecuteQuery(query);
            if (nr is DBNull) return 1;
            return ((int)nr + 1);
        }

    }
}