using System.Globalization;
using System.Text.RegularExpressions;
using Infrastructure;
using NetTopologySuite.Geometries;
using OpenAuth.App.BaseApp.Base;
using OpenAuth.App.Interface;
using OpenAuth.App.ServiceApp.ShpGeo.Request;
using OpenAuth.App.ServiceApp.ShpGeo.Response;
using OpenAuth.App.ServiceApp.ShpGeo.Utils;
using OpenAuth.Repository;
using OpenAuth.Repository.Domain;
using SqlSugar;

namespace OpenAuth.App.ServiceApp.ShpGeo;

public class GeoTiffManagerApp : SqlSugarBaseApp<GeoTiffManager, SugarDbContext>
{
    public GeoTiffManagerApp(ISugarUnitOfWork<SugarDbContext> unitWork,
        ISimpleClient<GeoTiffManager> repository, IAuth auth) : base(unitWork, repository, auth)
    {
    }

    // 影像管理列表
    public async Task<Response<PageInfo<List<GeoTiffManager>>>> LoadPage(GeoTiffManagerReq req)
    {
        RefAsync<int> totalCount = 0;
        var sources = await base.Repository.AsQueryable()
            .WhereIF(!string.IsNullOrEmpty(req.key), a => a.DataTable.Contains(req.key))
            .Select<GeoTiffManager>(a => new GeoTiffManager
            {
                Id = a.Id,
                CreateTime = a.CreateTime,
                UpdateTime = a.UpdateTime,
                DataTable = a.DataTable,
                TiffPath = a.TiffPath,
                ShpPath = a.ShpPath,
                DateDir = a.DateDir,
                LayerName = a.LayerName,
                StoreName = a.StoreName,
                AccessUrl = a.AccessUrl
            })
            .ToPageListAsync(req.page, req.limit, totalCount);

        return new Response<PageInfo<List<GeoTiffManager>>>
        {
            Result = new PageInfo<List<GeoTiffManager>>
            {
                Items = sources,
                Total = totalCount
            }
        };
    }

    /// <summary>
    /// 影像管理详情
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public GeoTiffManager Get(string id)
    {
        return Repository.GetById(id);
    }


    /// <summary>
    /// 影像更新
    /// </summary>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    public async Task<Response<List<string>>> UpdateGeoTiff()
    {
        var geoContext = GeoContext.Instance;
        var workspace = geoContext.Workspace;
        // 影像存放目录
        var tiffDir = geoContext.TiffDir; // 配置TIF目录，到目录tiff
        var geoserver = geoContext.GeoserverUrl;
        var tiffStoreNamePrefix = geoContext.TiffStoreNamePrefix;
        //  1. 先行查找shp(压缩包形式) 2. 解压 3. 读取shp记录（tif位置，） 4. 取得日期目录，取得tif文件路径信息
        // 5. 判断是否已经入库（全路径匹配） 6. 若没有入库，边界图形和tif信息一起存入tif表中
        var dirInfo = new DirectoryInfo(tiffDir);
        var db = Repository.AsSugarClient();
        // 获取所有文件，包括子目录中的文件
        var zipFiles = dirInfo.GetFiles("*.shp", SearchOption.AllDirectories);
        var errorList = new List<string>();
        foreach (var fileInfo in zipFiles) //所有边界文件
        {
            var shpDir = fileInfo.DirectoryName; // zip所有目录
            Console.WriteLine("shp路径：" + fileInfo.FullName);
            // 取得shp中数据
            var shpData = ShapeUtil.ReadAllGeometry(fileInfo.FullName);
            foreach (var data in shpData)
            {
                // shp 中字段有 Shape  Image LayerName  日期暂时没有
                // chengguo  日期（区域 * n（tif） zip）
                // tiff 文件全路径
                var geometry1 = (Geometry)data["Geometry"]; // 图形
                //var tifName = data["LayerName"].ToString(); //abc.tif 影像名称
                var relativeTifPath = data["Image"].ToString(); // TIF 相对路径 or 相对路径
                if (string.IsNullOrEmpty(relativeTifPath)) // 没有路径，跳过
                {
                    continue;
                }

                var tifName = Path.GetFileName(relativeTifPath); // tif名称
                if (string.IsNullOrEmpty(tifName))
                {
                    continue;
                }

                // \\\\192.168.10.100\\c\\ChengGuoFinal
                string tiffPath;
                var isRelativePath = false;
                // 判断相对路径还是绝对路径
                if (Regex.IsMatch(relativeTifPath, "^[a-zA-Z]")) // 若是绝对路径
                {
                    tiffPath = relativeTifPath;
                }
                else
                {
                    isRelativePath = true;
                    tiffPath = "C:\\ChengGuoFinal\\tiff" + relativeTifPath;
                }

                // todo  验证tiff 存不存修改  相对路径时，不用特别修改 
                var tempAccessPath = "";
                var isNetworkFile = false;
                // 关于如果tif不存在如何处理
                if (tiffDir.Contains(".")) // 包含IP
                {
                    isNetworkFile = true;
                    // \无人机巡飞影像数据\20241012\沂南县\20241012沂南15-19_0.2.tif
                    // \\\\192.168.10.100\\c\\ChengGuoFinal
                    // C:\ChengGuoFinal\tiff\无人机巡飞影像数据\20250112\费县\20250112费县1-2-0.2.tif
                    tempAccessPath = tiffPath.Replace("C:\\ChengGuoFinal\\tiff\\", tiffDir)
                        .Replace("c:\\ChengGuoFinal\\tiff", tiffDir);
                    if (!File.Exists(tempAccessPath))
                    {
                        // todo  临时注释
                        continue;
                    }

                    //tiffPath = tempAccessPath;
                }
                else if (!File.Exists(tiffPath))
                {
                    continue;
                }

                tiffPath = tiffPath.Replace("\\", "/"); // 统一路径分隔符 反斜杠换成斜杠
                var tiffName = Path.GetFileNameWithoutExtension(tiffPath);
                //var tempPath = isRelativePath ? relativeTifPath : tiffPath;
                // 路径完全相同，不需要处理
                var exist = await Repository.AsQueryable()
                    .Where(t => t.TiffPath.Equals(tiffPath)).AnyAsync();
                if (exist)
                {
                    continue;
                }
                // todo  C:\ChengGuoFinal\tiff
                var shpPath = fileInfo.FullName.Replace( tiffDir,"C:\\ChengGuoFinal\\tiff\\")
                    .Replace( tiffDir,"c:\\ChengGuoFinal\\tiff");
                // tiff 文件路径不同，但日期文件夹相同 更新tiff
                // todo 取得日期目录
                var dateDir = Path.GetFileName(Path.GetDirectoryName(shpPath));
                if (Path.GetFileNameWithoutExtension(shpPath).Equals("polygon")) // 针对使用qm生成的边界
                {
                    // 存在多个日期时，前下划线之前
                    dateDir = dateDir.Split("_")[0];
                }

                // 以zip文件存在
                // 新图层名称..   TIF名称中含有.
                tiffName = tiffName
                    .Replace(".tif", "")
                    .Replace("_", "")
                    .Replace(".", "")
                    .Replace("aux", "");
                var layerName = tiffName + DateTime.Now.ToString("yyyyMMddHHmmss");
                // 新栅格仓库名称
                var storeName = tiffStoreNamePrefix + tiffName +
                                DateTime.Now.ToString("yyyyMMddHHmmss");

                var record = new GeoTiffManager
                {
                    ShpPath = shpPath,
                    TiffPath = tiffPath,
                    DateDir = dateDir,
                    UpdateTime = DateTime.Now,
                    LayerName = layerName,
                    StoreName = storeName,
                    geometry = geometry1.AsText()
                };

                // 开启事务
                //await db.Ado.BeginTranAsync();
                var tableName = "tiff" + layerName;

                // todo 传入坐标
                // 新发布tiff
                var isSuccess = await GeoUtil.PublishExternalGeoTIFF("", tiffPath, storeName, layerName);
                if (!isSuccess.Result)
                {
                    errorList.Add(tiffPath);
                    continue;
                    //throw new Exception("tiff影像发布失败");
                }

                record.CreateTime = DateTime.Now;
                record.Id = Guid.NewGuid().ToString();
                record.DataTable = tableName;
                //record.CountyName = tiffFileInfo.Directory?.Name;
                var tiffLayerInfoResponse = await GeoUtil.GetTiffLayerInfo("", storeName, layerName);
                var bbox = tiffLayerInfoResponse.Result.bbox;
                var srs = tiffLayerInfoResponse.Result.srs;
                var accessUrl =
                    $"{geoserver}/{workspace}/wms?service=WMS&version=1.1.0&request=GetMap&layers={workspace}:{layerName}&bbox={bbox}&width=768&height=571&srs={srs}&styles=&format=application/openlayers";
                record.AccessUrl = accessUrl;
                await Repository.AsInsertable(record).ExecuteCommandAsync();

                // 判断是否存在对应图层组 如不存在则创建，如果存在，则添加图层
                var date = DateTime.ParseExact(dateDir, "yyyyMMdd", CultureInfo.InvariantCulture);
                var year = date.Year;
                var week = date.GetWeekOfYear();
                var layerGroupName = $"{year}-{week}";
                // todo  取出图层组图层
                // 判断图层组是否存在 
                if (await GeoUtil.ExistLayerGroup("", layerGroupName))
                {
                    await GeoUtil.AddLayersToLayerGroup("", layerGroupName, new List<string> { layerName });
                }
                else
                {
                    var layers = $"<layer>{workspace}:{layerName}</layer>";
                    await GeoUtil.publishLayerGroup("", layers, layerGroupName);
                }

                // 下载图片
                /*try
                {
                    const string fixedBbox =
                        "117.34046403513817,34.331716698906675,119.27763051149853,36.263686454243626";
                    var layerGroupThumbPath = "C:\\FileSystem\\web\\geoserver\\group";
                    // 创建目标目录（如果不存在）
                    if (!Directory.Exists(layerGroupThumbPath))
                    {
                        Directory.CreateDirectory(layerGroupThumbPath);
                    }

                    var layerGroupThumb = layerGroupName + ".png";
                    // 完整的目标文件路径
                    string filePath = Path.Combine(layerGroupThumbPath, layerGroupThumb);
                    var pngLink =
                        $"{geoserver}/{workspace}/wms?service=WMS&version=1.1.0&request=GetMap&layers={workspace}:{layerGroupName}&bbox={fixedBbox}&width=4096&height=4096&srs=EPSG:4326&styles=&TRANSPARENT=TRUE&format=image%2Fpng";
                    using (var client = new HttpClient())
                    {
                        using (var response = await client.GetAsync(pngLink))
                        {
                            response.EnsureSuccessStatusCode(); // 确保请求成功

                            // 将图片数据写入文件
                            await using (var fileStream =
                                         new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
                            {
                                await response.Content.CopyToAsync(fileStream);
                            }
                        }
                    }

                    Console.WriteLine($"图片已成功下载到: {filePath}");
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }*/
            }
        }

        // 提交事务
        //await db.Ado.CommitTranAsync();
        if (errorList.Count > 0)
        {
            return new Response<List<string>>
            {
                Result = errorList,
                Message = "以下影像tif发布失败：" + string.Join(",", errorList)
            };
        }

        return new Response<List<string>>
        {
            Result = new List<string>()
        };
    }

    public string Test(string storeName, string layerName)
    {
        var tiffLayerInfoResponse = GeoUtil.GetTiffLayerInfo1("", storeName, layerName);
        return tiffLayerInfoResponse.Result.ToString();
        //var db = Repository.AsSugarClient();
        //db.DbMaintenance.TruncateTable("parse_shpinfo_text3");
    }


    public async Task<PageInfo<List<TifInfo>>> GetIntersects(GeoTiffManagerReq req)
    {
        using var db = Repository.AsSugarClient();
        var sql =
            $@"select id as ""tifId"", layer_name as ""tifName"", access_url as ""accessUrl"" from geo_tiff_manager where ST_Intersects('{req.TargetShape}'::geometry,geometry)";

        var geoserverUrl = GeoUtil.GeoserverUrl;
        var workspace = GeoUtil.Workspace;
        var geoserverAccess =
            @$"{geoserverUrl}/{workspace}/wms?service=WMS&version=1.1.0&request=GetMap&layers={workspace}:LAYER_NAME&styles=&bbox={{bbox-epsg-3857}}&width=256&height=256&srs=EPSG:3857&format=image/png&TRANSPARENT=TRUE";
        RefAsync<int> totalCount = 0;
        var result = await db.SqlQueryable<TifInfo>(sql).ToPageListAsync(req.page, req.limit, totalCount);
        foreach (var tifInfo in result)
        {
            tifInfo.AccessUrl = geoserverAccess.Replace("LAYER_NAME", tifInfo.TifName);
        }

        return new PageInfo<List<TifInfo>>()
        {
            Items = result
        };
    }


    /// <summary>
    /// 影像创建图层组
    /// </summary>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    public async Task<Response<bool>> GroupGeoTiff(string type)
    {
        string layer = "";
        if ("0".Equals(type))
        {
            string myworkspace = "mylayergroup";
            var exist = await GeoUtil.ExistWorkspace(myworkspace);
            if (exist.Result)
            {
                await GeoUtil.DeleteWorkspace(myworkspace);
            }

            await GeoUtil.CreateWorkspace(myworkspace);
            var geoContext = GeoContext.Instance;

            // 影像存放目录
            var tiffDir = "C:\\合图数据\\1031合图"; // 配置目录
            var geoserver = geoContext.GeoserverUrl;
            var tiffStoreNamePrefix = geoContext.TiffStoreNamePrefix;
            // todo 1。 先行查找shp(压缩包形式) 2。解压 3。读取shp记录（tif位置，） 4。取得日期目录，取得tif文件路径信息
            // todo 5. 判断是否已经入库（全路径匹配） 6。若没有入库，边界图形和tif信息一起存入tif表中
            var dirInfo = new DirectoryInfo(tiffDir);
            var db = Repository.AsSugarClient();
            // 获取所有文件，包括子目录中的文件
            var zipFiles = dirInfo.GetFiles("*.tif", SearchOption.AllDirectories);
            foreach (var fileInfo in zipFiles)
            {
                var shpDir = fileInfo.DirectoryName; // tif所有目录
                string filename = fileInfo.FullName;


                var tiffName = Path.GetFileNameWithoutExtension(filename);
                // 新图层名称..   TIF名称中含有.
                var layerName = tiffName.Replace(".", "").Replace("aux", "") + DateTime.Now.ToString("yyyyHHmmss");
                // 新栅格仓库名称
                var storeName = tiffStoreNamePrefix + tiffName +
                                DateTime.Now.Millisecond;
                // 新发布tiff
                var isSuccess = await GeoUtil.PublishSingleGeoTIFF(myworkspace, filename, storeName, layerName);
                layer = layer + "<layer>" + myworkspace + ":" + layerName + "</layer>";
                if (!isSuccess.Result)
                {
                    // throw new Exception("tiff影像发布失败");
                }
            }

            await GeoUtil.publishLayerGroup(myworkspace, layer, "linyiAllYingxiang");
            return new Response<bool>
            {
                Result = true
            };
        }
        else
        {
            string myworkspace = "yaoganlayergroup";
            var exist = await GeoUtil.ExistWorkspace(myworkspace);
            if (exist.Result)
            {
                await GeoUtil.DeleteWorkspace(myworkspace);
            }

            await GeoUtil.CreateWorkspace(myworkspace);
            var geoContext = GeoContext.Instance;

            // 影像存放目录
            var tiffDir = "C:\\合图数据\\遥感影像全市"; // 配置目录
            var geoserver = geoContext.GeoserverUrl;
            var tiffStoreNamePrefix = geoContext.TiffStoreNamePrefix;
            // todo 1。 先行查找shp(压缩包形式) 2。解压 3。读取shp记录（tif位置，） 4。取得日期目录，取得tif文件路径信息
            // todo 5. 判断是否已经入库（全路径匹配） 6。若没有入库，边界图形和tif信息一起存入tif表中
            var dirInfo = new DirectoryInfo(tiffDir);
            var db = Repository.AsSugarClient();
            // 获取所有文件，包括子目录中的文件
            var zipFiles = dirInfo.GetFiles("*.tif", SearchOption.AllDirectories);
            foreach (var fileInfo in zipFiles)
            {
                var shpDir = fileInfo.DirectoryName; // tif所有目录
                string filename = fileInfo.FullName;
                var tiffPath = shpDir + filename;

                var tiffName = Path.GetFileNameWithoutExtension(filename);
                // 新图层名称..   TIF名称中含有.
                var layerName = tiffName.Replace(".", "") + DateTime.Now.ToString("yyyyHHmmss");
                // 新栅格仓库名称
                var storeName = tiffStoreNamePrefix + tiffName +
                                DateTime.Now.Millisecond;
                // 新发布tiff
                var isSuccess = await GeoUtil.PublishSingleGeoTIFF(myworkspace, filename, storeName, layerName);
                layer = layer + "<layer>" + myworkspace + ":" + layerName + "</layer>";
                if (!isSuccess.Result)
                {
                    throw new Exception("tiff影像发布失败");
                }
            }

            await GeoUtil.publishLayerGroup(myworkspace, layer, "yanganyingxiang");
            return new Response<bool>
            {
                Result = true
            };
        }
    }

    public async Task<Response<bool>> DeleteTifStore(string stores)
    {
        var storeList = stores.Split(",").ToList();
        var failList = new List<string>();
        foreach (var se in storeList)
        {
            await Repository.DeleteAsync(u => u.StoreName == se);
            // todo 删除图层
            try
            {
                await GeoUtil.DeleteCoveragesStore("", se, true);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                failList.Add(se);
            }
        }

        return new Response<bool>
        {
            Result = true,
            Message = string.Join(",", failList)
        };
    }

    public async Task<Response<bool>> UpdateLayerGroupThumb(string layerGroups, string bbox, int num, int height,
        int width)
    {
        var geoContext = GeoContext.Instance;
        var workspace = geoContext.Workspace;
        var geoserver = geoContext.GeoserverUrl;
        var layerGroupList = layerGroups.Split(",").ToList();
        if (string.IsNullOrEmpty(bbox))
        {
            bbox = "117.34046403513817,34.331716698906675,119.27763051149853,36.263686454243626";
        }

        var coordinate = bbox.Split(",").Select(double.Parse).ToArray();
        var minx = coordinate[0];
        var miny = coordinate[1];
        var maxx = coordinate[2];
        var maxy = coordinate[3];
        var stepX = (maxx - minx) / num;
        var stepY = (maxy - miny) / num;
        var layerGroupThumbPath = "C:\\FileSystem\\web\\geoserver\\group";
        foreach (var layerGroupName in layerGroupList)
        {
            var tempPath = layerGroupThumbPath;
            // 不同图层组，不同路径
            tempPath = Path.Combine(layerGroupThumbPath, num.ToString());
            tempPath = Path.Combine(tempPath, layerGroupName);
            // 完整的目标文件路径
            // 创建目标目录（如果不存在）
            if (!Directory.Exists(tempPath))
            {
                Directory.CreateDirectory(tempPath);
            }

            // 下载图片
            try
            {
                for (var i = 0; i < num; i++)
                {
                    for (var j = 0; j < num; j++)
                    {
                        var bboxCopy =
                            $"{minx + i * stepX},{miny + j * stepY},{minx + (i + 1) * stepX},{miny + (j + 1) * stepY}";
                        var layerGroupThumb = layerGroupName + "-" + i + "-" + j + ".png";
                        if (num == 1)
                        {
                            layerGroupThumb = layerGroupName + ".png";
                        }

                        // 完整的目标文件路径
                        string filePath = Path.Combine(tempPath, layerGroupThumb);
                        var pngLink =
                            $"{geoserver}/{workspace}/wms?service=WMS&version=1.1.0&request=GetMap&layers={workspace}:{layerGroupName}&bbox={bboxCopy}&width={width}&height={height}&srs=EPSG:4326&styles=&TRANSPARENT=TRUE&format=image%2Fpng";
                        using (var client = new HttpClient())
                        {
                            using (var response = await client.GetAsync(pngLink))
                            {
                                response.EnsureSuccessStatusCode(); // 确保请求成功

                                // 将图片数据写入文件
                                await using (var fileStream =
                                             new FileStream(filePath, FileMode.Create, FileAccess.Write,
                                                 FileShare.None))
                                {
                                    await response.Content.CopyToAsync(fileStream);
                                }
                            }
                        }

                        //Console.WriteLine($"图片已成功下载到: {filePath}");
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }

        return new Response<bool>
        {
            Result = true
        };
    }

    public dynamic GetTifCrs(string filePath)
    {
        return GeoUtil.GetTifCrs(filePath);
    }
}