using OpenAuth.App.BaseApp.Base;
using OpenAuth.Repository.Domain.FireManagement;
using OpenAuth.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenAuth.Repository.Domain;
using Microsoft.Extensions.Options;
using OpenAuth.App.Common;
using OpenAuth.App.Interface;
using SqlSugar;
using System.Net.WebSockets;
using Microsoft.Extensions.Configuration;
using Infrastructure;
using OpenAuth.App.ServiceApp.FireManagement.Request;
using OpenAuth.App.ServiceApp.FmPreventionPlanManage.Request;
using Yitter.IdGenerator;
using OpenAuth.App.Const;
using NetTopologySuite.Geometries;
using NetTopologySuite.IO;
using System.IO.Compression;
using Org.BouncyCastle.Ocsp;
using DocumentFormat.OpenXml.EMMA;
using DocumentFormat.OpenXml.Office2010.Excel;
using DocumentFormat.OpenXml.Spreadsheet;

namespace OpenAuth.App.ServiceApp.FmPreventionPlanManage
{
    public class FmPreventionPlanApp : SqlSugarBaseApp<FmPreventionplan, SugarDbContext>
    {

        private ClientWebSocket _socket;
        private IConfiguration _configuration;

        public FmPreventionPlanApp(IConfiguration configuration,  ISugarUnitOfWork<SugarDbContext> unitWork,ISimpleClient<FmPreventionplan> repository, IAuth auth) : base(unitWork, repository, auth)
        {
            _auth = auth;
            _configuration = configuration;
        }

        /// <summary>
        /// 分页查询预案列表
        /// </summary>
        /// <returns></returns>
        public async Task<Response<PageInfo<List<FmPreventionplan>>>> GetPreventionplanPageList(FmPreventionplanReq req)
        {
            using (var db = base.UnitWork.CreateContext())
            {
                RefAsync<int> totalNumber = 0;
                var infos = await db.FmPreventionplan.AsQueryable()
                    .Where(r=>r.IsDelete==false)
                    .WhereIF(req.state != null, r => r.Status == req.state)
                    .WhereIF(req.plancategory != null, r => r.PlanCategory == req.plancategory)
                    .WhereIF(req.createtimebegin != null && req.createtimeend != null, r => r.CreateTime >= req.createtimebegin && r.CreateTime <= req.createtimeend)
                    .WhereIF(!string.IsNullOrEmpty(req.name), r => r.PlanName.Contains(req.name))
                    .WhereIF(!string.IsNullOrEmpty(req.code), r => r.PlanCode.Contains(req.code))
                    .ToPageListAsync(req.page, req.limit, totalNumber);
                return new Response<PageInfo<List<FmPreventionplan>>>
                {
                    Result = new PageInfo<List<FmPreventionplan>> { Items = infos, Total = totalNumber }
                };
            }
        }


        /// <summary>
        /// 查询应急预案详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<Response<FmPreventionplan>> LoadClueInfoById(string id)
        {
            using (var db = base.UnitWork.CreateContext())
            {
                var info = await db.FmPreventionplan.AsQueryable()
                    .FirstAsync(r => r.Id == id);
                return new Response<FmPreventionplan> { Result = info };
            }
        }


        //删除应急预案
        public async Task<Response<bool>> DeletePreventionplan(string id)
        {
            using (var db = base.UnitWork.CreateContext())
            {
                var taskinfo = await db.FmPreventionplan.AsQueryable().FirstAsync(r => r.Id == id);
                if (taskinfo != null) 
                {
                    var flag=await db.FmPreventionplan.UpdateAsync(r => new FmPreventionplan
                    {
                        IsDelete = true
                    }, r => r.Id == id);
                    if (db.Commit()&&flag)
                    {
                        return new Response<bool> { Result = true, Message = "操作成功" };
                    }
                    else
                    {
                        return new Response<bool> { Result = false, Message = "操作失败" };
                    }
                }
                else
                {
                    return new Response<bool> { Result = false, Message = "预案不存在" };
                }
            }
        }

        //添加预案
        public async Task<Response<bool>> AddPreventionplan(PrePlanAddReq req)
        {
            using (var db = base.UnitWork.CreateContext())
            {
                FmPreventionplan info = req.MapTo<FmPreventionplan>();
                var user = _auth.GetCurrentUser().User;
                info.Id = Guid.NewGuid().ToString();
                info.CreateTime = DateTime.Now;
                info.CreateUser = user.Name;
                info.IsDelete = false;
                if (string.IsNullOrEmpty(info.PlanCode))
                {
                    throw new Exception("请输入预案编号");
                }
                
                var exitinfo = db.FmPreventionplan
                    .AsQueryable()
                    .Count(a => a.PlanCode==info.PlanCode);
                if (exitinfo > 0)
                {
                    throw new Exception("预案编号已存在，请重新输入");
                }

                FmPrePlanGeom geom = new FmPrePlanGeom();
                geom.Id = Guid.NewGuid().ToString();
                geom.PrePlanId = info.Id;

                string _wktModel = req.geom;

                geom.geom = null;
                if (!string.IsNullOrEmpty(req.geom))
                {
                    StringBuilder geomSql = new StringBuilder();
                    geomSql.AppendFormat(
                        $" update fm_preplangeom set \"geom\" = st_geomfromtext('{_wktModel}',4326) where \"Id\" = '{geom.Id}'");
                    var flag = await db.FmPreventionplan.InsertAsync(info);
                    var geomflag = await db.FmPrePlanGeom.InsertAsync(geom);
                    // 然后更新几何字段
                    if (flag && geomflag)
                    {
                        // 等待异步操作完成
                        var affectedRows = await db.Db.Ado.ExecuteCommandAsync(geomSql.ToString());

                        if (affectedRows > 0)
                        {
                            if (db.Commit())
                            {
                                return new Response<bool> { Result = true, Message = "操作成功" };
                            }
                        }
                    }
                }
                else
                {
                    // 如果没有几何数据，只插入主记录
                    var flag = await db.FmPreventionplan.InsertAsync(info);
                    var geomFlag = await db.FmPrePlanGeom.InsertAsync(geom);

                    if (flag && geomFlag && db.Commit())
                    {
                        return new Response<bool> { Result = true, Message = "操作成功" };
                    }
                }

                // 如果执行到这里，说明操作失败
                return new Response<bool> { Result = false, Message = "操作失败" };
            }
        }


        #region 备用代码
        //添加预案范围
        private async Task<StringBuilder> ReadShapefile(string zipFilePath, string Id)
        {
            var extractPath = zipFilePath.Substring(0, zipFilePath.LastIndexOf(".")) + "extract";
            //解压缩
            await UnZip(zipFilePath, extractPath);
            var searchPattern = "*.shp"; // 设置你想要遍历的文件后缀名
            var fileName = Directory.GetFiles(extractPath, searchPattern, SearchOption.AllDirectories);
            string shpFileName = fileName[0];
            // 创建一个 ShapefileDataReader 对象
            using (var reader = new ShapefileDataReader(shpFileName, GeometryFactory.Default))
            {
                StringBuilder geomSql = new StringBuilder();
                while (reader.Read())
                {
                    // 获取几何数据
                    Geometry geometry = reader.Geometry;
                    if (!geometry.IsValid)
                    {
                        throw new Exception("图斑未闭合，请重新整理数据");
                    }

                    // 如果几何数据是一个多边形（Polygon），需要转换为 MultiPolygon
                    MultiPolygon multiPolygon;
                    if (geometry is Polygon polygon)
                    {
                        // 单个Polygon转MultiPolygon
                        multiPolygon = new MultiPolygon(new[] { polygon });
                    }
                    else if (geometry is MultiPolygon existingMultiPolygon)
                    {
                        // 如果已经是MultiPolygon，直接使用
                        multiPolygon = existingMultiPolygon;
                    }
                    else
                    {
                        // 如果是其他类型的几何图形，可以根据需求进行处理
                        throw new Exception("几何图形不是多边形或多重多边形类型");
                    }

                    // 将几何数据转换为 WKT 格式，并用 SRID 4326
                    var geometryForWgs84 = multiPolygon.Copy();
                    geometryForWgs84.SRID = 4326;
                    //var geometryForWgs84 = GeometryFactory.Default.WithSRID(4326).CreateGeometry(geometry);
                    geomSql.AppendFormat(
                        $" update drone_shp_data set geom = '{geometryForWgs84.AsText()}' where \"relid\" = '{Id}';");
                }

                return geomSql;
            }
        }

        private static async Task UnZip(string zipFilePath, string extractPath)
        {
            await Task.Run(() =>
            {
                Directory.CreateDirectory(extractPath);
                // 设置字符编码
                Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
                var gbk = Encoding.GetEncoding("utf-8");
                using (var archive = ZipFile.OpenRead(zipFilePath))
                {
                    // 列举ZIP文件中的条目
                    foreach (var entry in archive.Entries)
                    {
                        var xxx = gbk.GetString(Encoding.Default.GetBytes(entry.FullName));
                        Console.WriteLine(xxx);
                    }

                    // 提取ZIP文件中的所有文件到指定目录

                    foreach (var entry in archive.Entries)
                    {
                        if (entry.Name != string.Empty)
                        {
                            // 确保完整路径存在  entry.FullName 是否可以编码
                            var fixedEntryName = entry.FullName.Replace("/", "");
                            var destinationPath =
                                System.IO.Path.GetFullPath(System.IO.Path.Combine(extractPath, fixedEntryName));
                            Console.WriteLine("解压文件路径：" + destinationPath);
                            if (!destinationPath.StartsWith(System.IO.Path.GetFullPath(extractPath) +
                                                            System.IO.Path.DirectorySeparatorChar))
                            {
                                throw new UnauthorizedAccessException("试图提取的文件超出了目标文件夹的路径边界。");
                            }

                            // 提取条目到目标路径
                            entry.ExtractToFile(destinationPath, overwrite: true);
                        }
                    }
                }

                // 遍历解压目录，是否有shp后缀的文件
                if (!Directory.Exists(extractPath))
                {
                    throw new Exception("文件解压失败");
                }
            });
        }
        #endregion
    }
}
