using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using OliviaAddInPro.Model;
using OliviaAddInPro.Helper;
using System.Windows;

namespace OliviaAddInPro.Services
{
    public class FinProcServ
    {
        public void finEjecuta(Respuesta<TiposEjecucion> res, TratamientoComun inst)
        {
            Application.Current.Dispatcher.BeginInvoke(new Action<Respuesta<TiposEjecucion>, TratamientoComun>((p, v) => finEjecuta2(p, v)),res,inst);

        }
        
        public void finEjecuta2(Respuesta<TiposEjecucion> res, TratamientoComun inst)
        {
            String msg = string.Empty;
            String msg_err = "Errores en el proceso de importación de resultados";
            var resp2 = new Respuesta<string> { Value = string.Empty };

            var resp = new Respuesta<string> { Value = string.Empty };
            bool mal = false;
            try
            {
                //gestiona los flags, el estado de finok o finnok va en res.Vale
                if (res.HasError)
                {
                    msg = res.Error.First();
                    mal = true;
                    //actualiza los flags
                    OliviaGlob.RemoveFlagTipEjec(TiposEjecucion.FinEjecNOk);
                }
                else
                {
                    inst.ProgrSrc.Init("Importando resultados");
                    //actualiza los flags
                    OliviaGlob.RemoveFlagTipEjec(TiposEjecucion.FinEjecOk);
                    //importa resultados
                    string FtClssName = "";
                    resp = IniImport(out FtClssName);
                    if (resp.HasError)
                    {
                        msg = resp.Error.First();
                        mal = true;
                    }
                    else
                    {
                        ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run((Func<bool>)(() =>
                        {
                            string GdbFileName = resp.Value;
                            string nombAmbitos = string.Empty;
                            if (OliviaGlob.HasFlagTipEjec(TiposEjecucion.EjecSecto)) //Ha terminado bien la sectorización
                            {
                                //actualiza los flags
                                //OliviaGlob.RemoveFlagTipEjec(TiposEjecucion.EjecSecto);
                                //acciones de importación
                                resp2 = inst.ServCom.ImportSecto(GdbFileName, FtClssName);
                            }
                            else if (OliviaGlob.HasFlagTipEjec(TiposEjecucion.EjecPlanif)) //Ha terminado bien la planificación
                            {
                                //actualiza los flags
                                //OliviaGlob.RemoveFlagTipEjec(TiposEjecucion.EjecPlanif);
                                //guarda csv
                                //GuardaCsv(inst); en finEjecuta3
                                //acciones de importación
                                resp2 = inst.ServCom.ImportPlanif(GdbFileName, FtClssName);

                            }
                            Application.Current.Dispatcher.BeginInvoke(new Action<Respuesta<string>, Respuesta<string>, bool, string, TratamientoComun>((p, v, x, u, w) => finEjecuta3(p, v, x, u, w)), resp, resp2, mal, msg, inst);
                            return true;
                        }));
                       
                    }
                }
            }
            catch(Exception ex)
            {
                msg = msg_err + ": "+msg+": "+ex.Message; 
                mal = true;
            }
            if (mal)
            {
                //actualiza los flags
                OliviaGlob.RemoveFlagTipEjec(TiposEjecucion.EjecPlanif);
                OliviaGlob.RemoveFlagTipEjec(TiposEjecucion.EjecSecto);

                HelperGlobal.ponMsg(msg);
                OliviaGlob.progrDialog.Hide();
                //muestra la ventana
                OliviaGlob.ShowHidePane(true);
                var task = ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
                {
                    //borra los archivos que le toca borrar
                    BorraFiles();
                });
            }
        }
        public void finEjecuta3(Respuesta<string> resp, Respuesta<string> resp2,bool mal, string msg, TratamientoComun inst)
        {
           
            String msg_err = "Errores en el proceso de importación de resultados";
            if (!mal)
            {
                try
                {
                    if (string.IsNullOrEmpty(resp2.Value))
                    {
                        //quita modo config2
                        OliviaGlob.RemoveFlagTipEjec(TiposEjecucion.Config2);
                        if (resp2.HasError)
                        {
                            msg = resp2.Error.First();
                        }
                        else
                            msg = msg_err;
                        mal = true;
                    }
                    else
                    {
                        //actualiza la capa de la que tiene que leer ahora para planificar 
                        inst.CapaPlanif = resp2.Value;
                        //pone modo config2
                        OliviaGlob.AddFlagTipEjec(TiposEjecucion.Config2);
                        if (OliviaGlob.HasFlagTipEjec(TiposEjecucion.EjecPlanif)) //Ha terminado bien la planificación
                        {
                            //guarda csv
                            GuardaCsv(inst,resp2.Value);
                        }
                        msg = Resource1.String_exito;                       
                        
                    }
                }
                catch (Exception ex)
                {
                    msg = msg_err + ": " + msg + ": " + ex.Message;
                    mal = true;
                }
            }            
            //actualiza los flags
            OliviaGlob.RemoveFlagTipEjec(TiposEjecucion.EjecPlanif);
            OliviaGlob.RemoveFlagTipEjec(TiposEjecucion.EjecSecto);            
            ///////////////////////////////////////////////////
            HelperGlobal.ponMsg(msg);
            OliviaGlob.progrDialog.Hide();
            //muestra la ventana
            OliviaGlob.ShowHidePane(true);
            var task = ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
            {
                //borra los archivos que le toca borrar
                BorraFiles();
            });
        }
        /**
         * Borra los archivos exportados para el proceso
         */
        public static void BorraFiles()
        {
            string[] list = null;
            string capa_principal, capa_principal_nw;
            if (!string.IsNullOrEmpty(OliviaGlob.Paths.PathData))
                capa_principal = System.IO.Path.GetFileNameWithoutExtension(OliviaGlob.Paths.PathData);
            else
                capa_principal = null;
            if (!string.IsNullOrEmpty(OliviaGlob.Paths.PathNW))
                capa_principal_nw = System.IO.Path.GetFileNameWithoutExtension(OliviaGlob.Paths.PathNW);
            else
                capa_principal_nw = null;            

            try
            {
                if (capa_principal != null && HelperGdb.CloseLayer(capa_principal))
                {
                    list = System.IO.Directory.GetFiles(OliviaGlob.Paths.DirData, capa_principal + "*");
                    if (list.Length > 0)
                    {
                        foreach (string f in list)
                        {
                            if (System.IO.Path.GetExtension(f) == ".lock")
                                continue;
                            System.IO.File.Delete(f);
                        }
                    }
                }
                if (capa_principal_nw != null && HelperGdb.CloseLayer(capa_principal_nw))
                {
                    list = System.IO.Directory.GetFiles(OliviaGlob.Paths.DirData, capa_principal_nw + "*");
                    if (list.Length > 0)
                    {
                        foreach (string f in list)
                        {
                            if (System.IO.Path.GetExtension(f) == ".lock")
                                continue;
                            System.IO.File.Delete(f);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        /*
         * Permite guardar el archivo CSV que contiene la secuencia que se ha llevado a cabo en las rutas en la planificación.
         */
        public static void GuardaCsv(TratamientoComun inst, string pathImport)
        {
            string auxi, nombre = null;
            string[] nameDokL;
            string DirData = System.IO.Path.GetDirectoryName(OliviaGlob.Paths.PathData);
            nameDokL = Directory.GetFiles(DirData,
                System.IO.Path.GetFileNameWithoutExtension(OliviaGlob.Paths.PathData) + inst.ServCom.NAME_CSV + ".*");

            string Title = "Directorio para guardar Secuencia de la Planificación";
            string Filter = "Secuencia en formato CSV (*.csv)|*.csv";
            inst.decode_gdb(System.IO.Path.GetFileNameWithoutExtension(OliviaGlob.Paths.PathData),
                    out auxi, out nombre);
            if (!string.IsNullOrEmpty(pathImport))
            {
                nombre = System.IO.Path.GetFileNameWithoutExtension(pathImport);
            }
            //string Path = HelperGdb.SaveFileDlg(Title, DirData, inst.ServCom.EXT_CSV, Filter);            
            string Path = string.Empty;
            if (OliviaGlob.CompruebaExistePath(OliviaGlob.Paths.PathGuardCsv))
                Path = OliviaGlob.Paths.PathGuardCsv;
            else
                //Path = HelperGdb.SaveFileDlg(Title, DirData, null, ArcGIS.Desktop.Catalog.ItemFilters.Folders);
                 Path = HelperGdb.FolderBrowseDlg(Title, DirData);
            if (string.IsNullOrEmpty(Path) || Path.Length == 0)
            {
                bool ok = HelperGlobal.ponMsg("Se va a perder el archivo que contiene la secuencia en planificación, ¿está seguro?", 
                    MessageBoxImage.Question,"OLIVIA",MessageBoxButton.YesNo);
                if (!ok)
                    GuardaCsv(inst, pathImport);
            }
            else
            {
                var FileName = System.IO.Path.Combine(Path, nombre);
                FileName += inst.ServCom.EXT_CSV;
                if (File.Exists(FileName))
                    File.Delete(FileName);
                File.Move(nameDokL[0], FileName);
            }
        }

        /*
        * Inicializa la importación
        */
        public Respuesta<string> IniImport(out string FtClssName)
        {
            var res = new Respuesta<string>() { Value = string.Empty };
            FtClssName = string.Empty;
            //Lanza ventana para elegir gdb a la que importar resultados            
            string GdbFileName="";
            if (OliviaGlob.CompruebaExistePath(OliviaGlob.Paths.PathGdbImport))
                GdbFileName = OliviaGlob.Paths.PathGdbImport;
            else
            {
                bool sal = true;               
                do
                {
                    sal = true;
                    //repite por si se ha equivocado hasta que elige la gdb
                    GdbFileName = HelperGdb.OpenFileDialog(HelperGdb.TiposOpenFileDlg.OpenGdb, "", "Seleccionar GDB a la que importar los resultados");

                    if (string.IsNullOrEmpty(GdbFileName))
                        sal = HelperGlobal.ponMsg("¿Desea cancelar el proceso de importación?",
                         MessageBoxImage.Question, "OLIVIA", MessageBoxButton.YesNo);
                } while (!sal);
            }
            if (string.IsNullOrEmpty(GdbFileName) || !Directory.Exists(GdbFileName))
            {
                res.Error.Add("Se ha cancelado la importación de resultados. Se cancela la elección de GDB.");
                return res;
            }
            res.Value = GdbFileName;
            
            if (string.IsNullOrEmpty(OliviaGlob.Paths.PathDatasetImport))
            { //ahora pide elegir nombre de ftclass
                FtClssName = HelperGdb.SaveFileDlg("Seleccione ubicación e introduzca nombre de Feature Class a importar", GdbFileName, null, ArcGIS.Desktop.Catalog.ItemFilters.FeatureClasses_All);
            }

            return res;
        }
    }
}
