using System;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.Windows.Forms;
using MercatorApi;
using MercatorUi;
using MercatorUi.Forms.Sig;
using MercatorUi.Wait;

namespace Main
{
    public class Customizer : MercatorUi.ICustomizers.IExec
    {
        public void Main(MercatorUi.ICustomizers.ExecAction Action)
        {
            if (Action == MercatorUi.ICustomizers.ExecAction.MenuCreated)
            {
                // Ajout menu sous Gestion pour mise à jour stock min sur base des ventes ancienne période
                var menu = _Divers.MenuElementByText(_Divers.Iif_langue(MercatorUi.Globals.Langue, "Verwaltung", "Administration", "Beheer", "Gestion"));
                if (menu != null)
                    menu.SubItems.Add(new MercatorUi._BaseClasses.MenuElement("Màj stocks MIN par période", "", null, StockMin_Click));
            }
        }

        void StockMin_Click(object sender, EventArgs e)
        {
            // Mise à jour stock min sur base des ventes ancienne période
            var depot = Dialogs.AskDepot("Pour quel dépôt ?");
            if (depot == null)
                return;

            bool bDefaultDepot = (Globals.DepotDef == depot.Id);

            var dates = Dialogs.AskDates("Sur quelle période se baser pour générer les nouvelles valeurs MIN de stock ?");
            if (dates == null || dates.GetLength(0) < 2)
                return;

            string filter = "";
            Form wonTop = Globals.Main.WonTopForm();
            if (wonTop != null)
            {
                var sigForm = wonTop as SigForm;
                if (sigForm != null && sigForm.Sig.Module == MercatorUi.Sig._SigEnum.STOCK)
                    filter = sigForm.Filter;
            }

            if (!string.IsNullOrEmpty(filter))
                if (!Dialogs.AnswerYesNo(string.Format("Appliquer le filtre '{0}' ?", filter)))
                    filter = "";
                else
                    filter = " and " + filter;

            string sqlQuery = @"select LIGNES_V.ID_ARTICLE, sum(LIGNES_V.Q) as Tot_Q
                                   from PIEDS_V
                                    inner join LIGNES_V on PIEDS_V.ID = LIGNES_V.ID and PIEDS_V.JOURNAL = LIGNES_V.JOURNAL and PIEDS_V.PIECE = LIGNES_V.PIECE
                                    inner join STOCK on LIGNES_V.ID_ARTICLE = STOCK.S_ID -- this join is needed for filters to work
                                   where (PIEDS_V.TYPE = 1)
                                         and (LIGNES_V.ID_ARTICLE <> '')
                                         and (PIEDS_V.DATE between @DATE_1 and @DATE_2)
                                    and LIGNES_V.Q <> 0
                                    and PIEDS_V.ID_DEPOT = @ID_DEPOT
                                    {0}
                                   group by ID_ARTICLE
                                   order by ID_ARTICLE";

            sqlQuery = string.Format(sqlQuery, filter);

            var paramDate1 = new MercatorSqlParam("@DATE_1", dates[0]);
            var paramDate2 = new MercatorSqlParam("@DATE_2", dates[1]);
            var paramDepot = new MercatorSqlParam("@ID_DEPOT", depot.Id);

            WaitStatic.WaitWindow("Calcul quantités vendues sur la période...");
            var dataSet = Api.Zselect(Globals.RepData, sqlQuery, paramDate1, paramDate2, paramDepot);
            WaitStatic.WaitClear();

            if (dataSet != null && dataSet.Tables.Count > 0 && dataSet.Tables[0].Rows.Count > 0)
            {
                if (Dialogs.AnswerYesNo(string.Format("{0} entrées trouvées\r\n\r\nMettre à jour les stocks min de ces articles ?", dataSet.Tables[0].Rows.Count)))
                {
                    Progress.ProgressCreate(dataSet.Tables[0].Rows.Count);
                    var stringBuilder = new StringBuilder();

                    // Mise à zéro de tous les articles retournés par le filtre (ou tous si pas de filtre)
                    if (bDefaultDepot)
                        stringBuilder.AppendFormat("update STOCK set S_STOCKMIN = 0 where S_STOCKMIN<>0{0}\r\n", filter);
                    stringBuilder.AppendFormat("update dispo set dispo.STOCKMIN = 0 from DISPO inner join STOCK on dispo.ID_STOCK = stock.S_ID where STOCKMIN<>0 and ID_MAGASIN = '{0}'{1}\r\n\r\n", depot.Id, filter);

                    Api.TrimDataTable(dataSet.Tables[0]);
                    foreach (DataRow row in dataSet.Tables[0].Rows)
                    {
                        decimal Q = Convert.ToDecimal(row["Tot_Q"]);
                        string s_id = (string)row["ID_ARTICLE"];

                        // Ajout 10%
                        Q = Math.Ceiling(Q * 1.1m);

                        if (bDefaultDepot)
                            stringBuilder.AppendFormat("update STOCK set S_STOCKMIN = {0} where S_ID = '{1}'\r\n", Q, s_id);

                        stringBuilder.AppendFormat("update DISPO set STOCKMIN = {0} where ID_STOCK = '{1}' and ID_MAGASIN = '{2}'\r\n\r\n", Q, s_id, depot.Id);

                        Progress.ProgressIncrement(1);
                    }

                    WaitStatic.WaitWindow("Mise à jour des stocks min...");

                    bool result = Api.SqlExec(Globals.RepData, new SqlCommand(stringBuilder.ToString()));
                    WaitStatic.WaitClear();
                    Progress.ProgressDestroy();

                    if (result)
                        Dialogs.Stop("Mise à jour terminée avec succès !");
                    else
                        Dialogs.Stop("Une erreur est survenue : " + Api.LastError);
                }
            }
            else
                Dialogs.Stop("Aucune vente d'article n'a été trouvée pour cette période et ce dépôt !");
        }
    }
}