using System.Data;
using Infrastructure;
using Infrastructure.Extensions;
using Infrastructure.Helpers;
using NetTopologySuite.IO;
using Newtonsoft.Json;
using NPOI.Util;
using OpenAuth.App.BasicQueryService;
using OpenAuth.App.ServiceApp.DroneCaseInfo.Request;
using OpenAuth.Repository;
using OpenAuth.Repository.Domain;
using SqlSugar;

namespace OpenAuth.App.ServiceApp.DroneCaseInfo;

public partial class DroneCaseInfoSingleApp
{
    public async Task<Response<string>> CaseSplit(CaseSplitReq req)
    {
        var authStrategyContext = _auth.GetCurrentUser();
        var user = authStrategyContext.User;
        //  案件分宗 1. 关闭案件 2.撤消流程 3. 新建案件流程（生成关联图斑记录） 4. 生成拆分案件及拆分前案件关联关系

        using var db = Repository.AsSugarClient();

        try
        {
            await db.Ado.BeginTranAsync(IsolationLevel.ReadCommitted);
            var original = await db.Queryable<DroneCaseInfoSingle>().FirstAsync(t => t.Id == req.caseid);
            var oriinalCaseNo = original.case_no;
            if (original == null)
            {
                throw new Exception("图斑不存在");
            }

            var wktReader = new WKTReader();
            foreach (var part in req.parts)
            {
                // 判断图斑是否正常
                var geometry = wktReader.Read(part.geom);
            }

            // 根据案件id取得流程
            var process = await Repository.ChangeRepository<SugarRepositiry<WFProcess>>().AsQueryable()
                .FirstAsync(t => t.Id == req.processid);

            // 作废流程
            var result = await _processApp.DeleteProcess(process.Id);
            // 生成拆分案件
            var caseList = new List<DroneCaseInfoSingle>(req.parts.Count);
            var relationships = new List<DroneCaseSplit>(req.parts.Count);
            var imageRefs = await Repository.ChangeRepository<SugarRepositiry<DroneImageRef>>().AsQueryable()
                .Where(t => t.CaseId == req.caseid)
                .Select(t => new DroneImageRef
                {
                    FilePath = t.FilePath,
                    Orientation = t.Orientation,
                    Lng = t.Lng,
                    Lat = t.Lat
                })
                .ToListAsync();
            using var httpClient = new HttpClient();
            // 	http://192.168.10.125:9011/DroneEnforcement/2024/20241112/Image_Water_1731054661277.jpeg
            var config = ConfigHelper.GetConfigRoot();
            var baseUrl = config["ImgServer"];
            var url = baseUrl + "/api/Platform/NewCopyImg";
            // 文件路径 字段
            var files = new Dictionary<string, string>();
            // 方向角图片
            var images = "";
            if (!string.IsNullOrEmpty(original.anjianzhaopian))
            {
                var temp = original.anjianzhaopian.Trim(',');
                var imgArray = temp.Split(",");
                foreach (var se in imgArray)
                {
                    files.Add(se, "anjianzhaopian");
                }

                images += "," + temp;
            }

            // 拆除复耕
            if (!string.IsNullOrEmpty(original.chaichufugenghoupic))
            {
                var temp = original.chaichufugenghoupic.Trim(',');
                var imgArray = temp.Split(",");
                foreach (var se in imgArray)
                {
                    files.Add(se, "chaichufugenghoupic");
                }

                images += "," + temp;
            }

            // 补办照片
            if (!string.IsNullOrEmpty(original.bubanzhaopian))
            {
                var temp = original.bubanzhaopian.Trim(',');
                var imgArray = temp.Split(",");
                foreach (var se in imgArray)
                {
                    files.Add(se, "bubanzhaopian");
                }

                images += "," + temp;
            }

            // 图斑图片
            if (!string.IsNullOrEmpty(original.casepic))
            {
                var temp = original.casepic.Trim(',');
                var imgArray = temp.Split(",");
                foreach (var se in imgArray)
                {
                    files.Add(se, "casepic");
                }

                images += "," + temp;
            }

            if (!string.IsNullOrEmpty(original.fujian))
            {
                var temp = original.fujian.Trim(',');
                var imgArray = temp.Split(",");
                foreach (var se in imgArray)
                {
                    files.Add(se, "fujian");
                }

                images += "," + temp;
            }

            // 整改附件
            if (!string.IsNullOrEmpty(original.zhenggaifujian))
            {
                var temp = original.zhenggaifujian.Trim(',');
                var imgArray = temp.Split(",");
                foreach (var se in imgArray)
                {
                    files.Add(se, "zhenggaifujian");
                }

                images += "," + temp;
            }

            // 合法附件
            if (!string.IsNullOrEmpty(original.hefafujian))
            {
                var temp = original.hefafujian.Trim(',');
                var imgArray = temp.Split(",");
                foreach (var se in imgArray)
                {
                    files.Add(se, "hefafujian");
                }

                images += "," + temp;
            }

            // 其它附近
            if (!string.IsNullOrEmpty(original.qitafujian))
            {
                var temp = original.qitafujian.Trim(',');
                var imgArray = temp.Split(",");
                foreach (var se in imgArray)
                {
                    files.Add(se, "qitafujian");
                }

                images += "," + temp;
            }

            // 无人机复飞
            if (!string.IsNullOrEmpty(original.wrjffzhaopian))
            {
                var temp = original.wrjffzhaopian.Trim(',');
                var imgArray = temp.Split(",");
                foreach (var se in imgArray)
                {
                    files.Add(se, "wrjffzhaopian");
                }

                images += "," + temp;
            }

            //现场核查照片
            if (!string.IsNullOrEmpty(original.xchczhaopian))
            {
                var temp = original.xchczhaopian.Trim(',');
                var imgArray = temp.Split(",");
                foreach (var se in imgArray)
                {
                    files.Add(se, "xchczhaopian");
                }

                images += "," + temp;
            }

            images = images.Trim(',');
            var param = new Dictionary<string, string>()
            {
                { "path", images }
            };
            var content = new FormUrlEncodedContent(param);
            var newImgRefs = new List<DroneImageRef>(imageRefs.Count * 2);
            var i = 1;
            foreach (var casePart in req.parts)
            {
                // todo 复制填充文件
                var caseInfo = original.MapTo<DroneCaseInfoSingle>();
                var caseId = Guid.NewGuid().ToString();
                caseInfo.Id = caseId;
                caseInfo.case_no = oriinalCaseNo + "-" + (i++);
                caseInfo.nongyongdi_area = casePart.nongyongdi_area;
                caseInfo.gengdi_area = casePart.gengdi_area;
                caseInfo.yongjiujibennongtian_area = casePart.yongjiujibennongtian_area;
                caseInfo.shengtaibaohuhongxian_area = casePart.shengtaibaohuhongxian_area;
                caseInfo.guotukongjianguihua_area = casePart.guotukongjianguihua_area;
                caseInfo.zhongdianquyu_area = casePart.zhongdianquyu_area;
                caseInfo.area = casePart.area;
                // 设置时间
                caseInfo.createtime = DateTime.Now;
                //  设置创建人
                caseInfo.createuser = user.Id + "";
                caseInfo.createusername = user.Name;

                // 清理数据
                caseInfo.anjianzhaopian = null;
                caseInfo.chaichufugenghoupic = null;
                caseInfo.bubanzhaopian = null;
                caseInfo.casepic = null;
                caseInfo.fujian = null;
                caseInfo.zhenggaifujian = null;
                caseInfo.hefafujian = null;
                caseInfo.qitafujian = null;
                caseInfo.wrjffzhaopian = null;
                caseInfo.xchczhaopian = null;

                // 复制图片
                if (!string.IsNullOrEmpty(images))
                {
                    var copyFileResponse = await httpClient.PostAsync(url, content);
                    if (copyFileResponse.IsSuccessStatusCode)
                    {
                        var resultContent = await copyFileResponse.Content.ReadAsStringAsync();
                        var obj = JsonConvert.DeserializeObject<Response<List<SysUploadFileNew>>>(resultContent);
                        if (!obj.Code.Equals(200))
                        {
                            throw new Exception("复制文件失败");
                        }

                        foreach (var sysUploadFileNew in obj.Result)
                        {
                            var originalPath = sysUploadFileNew.OriginalPath;
                            var newFilePath = sysUploadFileNew.FilePath;
                            var imgRef = imageRefs.FirstOrDefault(x => x.FilePath.Equals(originalPath));
                            if (imgRef != null)
                            {
                                // 填充信息
                                var temp = imgRef.Copy();
                                temp.Id = Guid.NewGuid().ToString();
                                temp.CaseId = caseInfo.Id;
                                temp.CreateTime = DateTime.Now;
                                temp.FilePath = newFilePath;
                                newImgRefs.Add(temp);
                            }

                            var field = files[originalPath];
                            switch (field)
                            {
                                case "fujian":
                                    if (string.IsNullOrEmpty(caseInfo.fujian))
                                    {
                                        caseInfo.fujian = newFilePath;
                                    }
                                    else
                                    {
                                        caseInfo.fujian = caseInfo.fujian + "," + newFilePath;
                                    }

                                    break;
                                case "anjianzhaopian":
                                    if (string.IsNullOrEmpty(caseInfo.anjianzhaopian))
                                    {
                                        caseInfo.anjianzhaopian = newFilePath;
                                    }
                                    else
                                    {
                                        caseInfo.anjianzhaopian = caseInfo.anjianzhaopian + "," + newFilePath;
                                    }

                                    break;
                                case "chaichufugenghoupic":
                                    if (string.IsNullOrEmpty(caseInfo.chaichufugenghoupic))
                                    {
                                        caseInfo.chaichufugenghoupic = newFilePath;
                                    }
                                    else
                                    {
                                        caseInfo.chaichufugenghoupic = caseInfo.chaichufugenghoupic + "," + newFilePath;
                                    }

                                    break;
                                case "bubanzhaopian":
                                    if (string.IsNullOrEmpty(caseInfo.bubanzhaopian))
                                    {
                                        caseInfo.bubanzhaopian = newFilePath;
                                    }
                                    else
                                    {
                                        caseInfo.bubanzhaopian = caseInfo.bubanzhaopian + "," + newFilePath;
                                    }

                                    break;
                                case "casepic":
                                    if (string.IsNullOrEmpty(caseInfo.casepic))
                                    {
                                        caseInfo.casepic = newFilePath;
                                    }
                                    else
                                    {
                                        caseInfo.casepic = caseInfo.casepic + "," + newFilePath;
                                    }

                                    break;
                                case "zhenggaifujian":
                                    if (string.IsNullOrEmpty(caseInfo.zhenggaifujian))
                                    {
                                        caseInfo.zhenggaifujian = newFilePath;
                                    }
                                    else
                                    {
                                        caseInfo.zhenggaifujian = caseInfo.zhenggaifujian + "," + newFilePath;
                                    }

                                    break;
                                case "hefafujian":
                                    if (string.IsNullOrEmpty(caseInfo.hefafujian))
                                    {
                                        caseInfo.hefafujian = newFilePath;
                                    }
                                    else
                                    {
                                        caseInfo.hefafujian = caseInfo.hefafujian + "," + newFilePath;
                                    }

                                    break;
                                case "qitafujian":
                                    if (string.IsNullOrEmpty(caseInfo.qitafujian))
                                    {
                                        caseInfo.qitafujian = newFilePath;
                                    }
                                    else
                                    {
                                        caseInfo.qitafujian = caseInfo.qitafujian + "," + newFilePath;
                                    }

                                    break;
                                case "wrjffzhaopian":
                                    if (string.IsNullOrEmpty(caseInfo.wrjffzhaopian))
                                    {
                                        caseInfo.wrjffzhaopian = newFilePath;
                                    }
                                    else
                                    {
                                        caseInfo.wrjffzhaopian = caseInfo.wrjffzhaopian + "," + newFilePath;
                                    }

                                    break;
                                case "xchczhaopian":
                                    if (string.IsNullOrEmpty(caseInfo.xchczhaopian))
                                    {
                                        caseInfo.xchczhaopian = newFilePath;
                                    }
                                    else
                                    {
                                        caseInfo.xchczhaopian = caseInfo.xchczhaopian + "," + newFilePath;
                                    }

                                    break;
                            }
                        }
                    }

                    else
                    {
                        throw new Exception("复制文件失败");
                    }
                }

                // todo 去掉某些属性值
                // 填充图斑信息
                var geometry = wktReader.Read(casePart.geom);
                var gidStr = _commonDataManager.GetMaxKeyVal("gid", "drone_shp_data", 1);
                var insertObj = new Dictionary<string, object>
                {
                    { "gid", gidStr.ToInt() },
                    { "geom", geometry.AsBinary() },
                    { "relid", caseId }
                };
                // 插入图斑
                await db.Insertable(insertObj).AS("drone_shp_data").ExecuteCommandAsync();
                caseInfo.geomid = gidStr;
                caseList.Add(caseInfo);
                // 原始案件与拆分案件关联
                var splitRelation = new DroneCaseSplit();
                splitRelation.NewCaseId = caseId;
                splitRelation.OriginalCaseId = req.caseid;
                relationships.Add(splitRelation);
            }

            if (newImgRefs.Count > 0)
            {
                await db.Insertable(newImgRefs).ExecuteCommandAsync();
            }

            await db.Insertable(caseList).ExecuteCommandAsync();
            //新案件与原始案件关联
            await db.Insertable(relationships).ExecuteCommandAsync();
            // 发起新流程
            foreach (var caseInfo in caseList)
            {
                var instanceInfo = process.InstanceInfo;
                instanceInfo.pkeyValue = caseInfo.Id;
                await _processApp.SaveDraft(caseInfo.Id, process.SchemeCode, user.Id + "",
                    JsonConvert.SerializeObject(instanceInfo), process.ParentProcessId, process.ParentNodeId,
                    process.ParentTaskId, 0,
                    caseInfo.case_description);
                await _processApp.Create(caseInfo.Id, "", user.Id + "", null, JsonConvert.SerializeObject(instanceInfo),
                    caseInfo.case_description);
            }

            // 关闭案件
            var record = new DroneCaseInfoSingle
            {
                Id = req.caseid,
                is_closed = 1,
                is_split = 1,
                close_userid = user.Id + "",
                close_user = user.Name,
                close_time = DateTime.Now
            };
            Console.WriteLine("运行前==========================================");
            var x = await db.Updateable(record).IgnoreNullColumns().ExecuteCommandAsync();
            Console.WriteLine("运行后============================================ " + x);
            await db.Ado.CommitTranAsync();
            return new Response<string>
            {
                Result = "拆分成功",
                Message = "拆分成功"
            };
        }
        catch (Exception e)
        {
            //恢复作废流程
            await _processApp.RecoverProcess(req.processid);
            await db.Ado.RollbackTranAsync();
            Console.WriteLine("当前时间：" + DateTime.Now.ToString());
            Console.WriteLine("异常信息：" + e.Message);
            Console.WriteLine("异常对象：" + e.Source);
            Console.WriteLine("调用堆栈：\n" + e.StackTrace);
            throw e;
        }
    }

    /// <summary>
    /// 根据子图斑恢复被分割图斑
    /// </summary>
    /// <param name="req"></param>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    public async Task<Response<string>> CaseRecover(CaseRecoverReq req)
    {
        var authStrategyContext = _auth.GetCurrentUser();
        var user = authStrategyContext.User;
        using var db = Repository.AsSugarClient();

        // 拆分案件数量
        var relationships = new List<DroneCaseSplit>(req.parts.Count);
        var caseId = Guid.NewGuid().ToString();
        try
        {
            await db.Ado.BeginTranAsync(IsolationLevel.ReadCommitted);
            var subCaseId = req.caseid;
            // 这里是验证当前选中的图斑，是否有被分割，但当和它一起被分割出来的图斑被分割时，还原该图斑会有问题
            // 以下代码校验指定图斑是否被分割过
            string sql5 =
                $"select new_case_id  from drone_case_split where original_case_id='{subCaseId}' and is_recover=0";
            var caseids1 = await db.Ado.SqlQueryAsync<string>(sql5);
            if (caseids1.Count > 0)
            {
                return new Response<string>
                {
                    Result = "当前图斑存在分割的子图斑不允许还原",
                    Message = "还原失败"
                };
            }

            var sql6 = @"SELECT
	                        count(*)
                          FROM
	                            drone_case_split s  join drone_caseinfo_single c on s.new_case_id = c.""Id"" and c.is_split = '1'
                          WHERE
	                        s.original_case_id = (select original_case_id from drone_case_split where new_case_id = @x)
	                        AND s.new_case_id != @x
	                        AND s.is_recover = '0'";
            var count = await db.Ado.SqlQuerySingleAsync<int>(sql6, new { x = subCaseId });
            if (count > 0)
            {
                return new Response<string>
                {
                    Result = "当前图斑一起分割的图斑存在分割的子图斑",
                    Message = "还原失败"
                };
            }

            if (req.type == 0) // 目前此值必定为0
            {
                var sql =
                    $"select original_case_id  from drone_case_split where new_case_id='{subCaseId}' and is_recover=0";
                // 原始图斑
                var oldCaseId = await db.Ado.SqlQuerySingleAsync<string>(sql);

                if (string.IsNullOrEmpty(oldCaseId))
                {
                    return new Response<string>
                    {
                        Result = "图斑未拆",
                        Message = "还原失败"
                    };
                }

                // 恢复还原图斑
                await _processApp.RecoverProcess(oldCaseId);
                // 还原案件
                await db.Updateable<DroneCaseInfoSingle>()
                    .SetColumns(c =>
                        new DroneCaseInfoSingle
                        {
                            is_closed = 0,
                            is_split = 2
                        }).Where(a => a.Id == oldCaseId).ExecuteCommandAsync();
                // 处理子图斑
                // 查询子图斑
                var subCaseQuery =
                    $"select new_case_id from drone_case_split where is_recover=0 and  original_case_id  = '{oldCaseId}'";
                var newCaseIds = db.Ado.SqlQuery<string>(subCaseQuery);
                foreach (var casePart in newCaseIds)
                {
                    // 作废流程
                    var result = await _processApp.DeleteProcess(casePart);
                    // todo  做意外处理，当执行失败时，
                    await db.Updateable<DroneCaseSplit>().SetColumns(c => new DroneCaseSplit
                    {
                        IsRecover = 1
                    }).Where(a => a.NewCaseId == casePart).ExecuteCommandAsync();
                    // 关闭
                    await db.Updateable<DroneCaseInfoSingle>().SetColumns(c => new DroneCaseInfoSingle
                    {
                        is_closed = 1
                    }).Where(a => a.Id == casePart).ExecuteCommandAsync();
                }

                await db.Ado.CommitTranAsync();
                return new Response<string>
                {
                    Result = "还原成功",
                    Message = "还原成功"
                };
            }
            else
            {
                foreach (var casePart in req.parts)
                {
                    var original = await db.Queryable<DroneCaseInfoSingle>().FirstAsync(t => t.Id == casePart.caseid);
                    // 关闭案件
                    var record = new DroneCaseInfoSingle
                    {
                        Id = casePart.caseid,
                        is_closed = 1
                    };
                    await db.Updateable(record).ExecuteCommandAsync();
                    // 根据案件id取得流程
                    var process2 = await Repository.ChangeRepository<SugarRepositiry<WFProcess>>().AsQueryable()
                        .Where(t => SqlFunc.JsonField(t.InstanceInfo, "pkeyValue").Equals(casePart.caseid))
                        .FirstAsync();
                    // 作废流程
                    var result = await _processApp.DeleteProcess(process2.Id);
                    var splitRelation1 = new DroneCaseSplit();
                    splitRelation1.NewCaseId = caseId;
                    splitRelation1.OriginalCaseId = casePart.caseid;
                    relationships.Add(splitRelation1);
                }

                await db.Insertable(relationships).ExecuteCommandAsync();
                // 生成新案件
                var caseList = new List<DroneCaseInfoSingle>();
                var original1 = await db.Queryable<DroneCaseInfoSingle>().FirstAsync(t => t.Id == req.parts[0].caseid);
                var process = await Repository.ChangeRepository<SugarRepositiry<WFProcess>>().AsQueryable()
                    .Where(t => SqlFunc.JsonField(t.InstanceInfo, "pkeyValue").Equals(original1.case_no))
                    .FirstAsync();
                var wktReader = new WKTReader();
                var caseInfo = original1.MapTo<DroneCaseInfoSingle>();
                caseInfo.Id = caseId;
                caseInfo.nongyongdi_area = req.nongyongdi_area;
                caseInfo.gengdi_area = req.gengdi_area;
                caseInfo.yongjiujibennongtian_area = req.yongjiujibennongtian_area;
                caseInfo.shengtaibaohuhongxian_area = req.shengtaibaohuhongxian_area;
                caseInfo.guotukongjianguihua_area = req.guotukongjianguihua_area;
                caseInfo.zhongdianquyu_area = req.zhongdianquyu_area;
                caseInfo.area = req.area;
                // 设置时间
                caseInfo.createtime = DateTime.Now;
                //  设置创建人
                caseInfo.createuser = user.Id + "";
                caseInfo.createusername = user.Name;
                // casepic zhenggaifujian chaichufugenghoupic anjianzhaopian  hefafujian qitafujian bubanzaopian  wrjffzhaopian无人机复飞 xchczhaopian现场核查照片  pro_phase_img later_phase_img
                // 
                // 填充图斑信息
                var geometry = wktReader.Read(req.geom);
                var gidStr = _commonDataManager.GetMaxKeyVal("gid", "drone_shp_data", 1);
                var insertObj = new Dictionary<string, object>
                {
                    { "gid", gidStr.ToInt() },
                    { "geom", geometry.AsBinary() }
                };
                // 插入图斑
                await db.Insertable(insertObj).AS("drone_shp_data").ExecuteCommandAsync();
                caseInfo.geomid = gidStr;
                caseList.Add(caseInfo);

                await db.Insertable(caseList).ExecuteCommandAsync();

                // 发起新流程
                var processId = Guid.NewGuid().ToString();
                var instanceInfo = process.InstanceInfo;
                instanceInfo.pkeyValue = caseInfo.Id;
                string x = Json.ToJson(instanceInfo);
                Console.WriteLine("instance: " + x);
                await _processApp.SaveDraft(caseInfo.Id, process.SchemeCode, user.Id + "",
                    Json.ToJson(instanceInfo), process.ParentProcessId, process.ParentNodeId, process.ParentTaskId, 0,
                    caseInfo.case_description);
                await _processApp.Create(caseInfo.Id, process.SchemeCode, user.Id + "", null, Json.ToJson(instanceInfo),
                    caseInfo.case_description);

                await db.Ado.CommitTranAsync();

                return new Response<string>
                {
                    Result = "拆分成功",
                    Message = "拆分成功"
                };
            }
        }
        catch (Exception e)
        {
            await db.Ado.RollbackTranAsync();
            throw e;
        }
    }
}