using System.Data;
using System.Text;
using Infrastructure;
using Infrastructure.Extensions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using NetTopologySuite.Geometries;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OpenAuth.App.BaseApp.Base;
using OpenAuth.App.FormScheme;
using OpenAuth.App.Interface;
using OpenAuth.App.ServiceApp.Request;
using OpenAuth.App.ServiceApp.Response;
using OpenAuth.Repository;
using OpenAuth.Repository.Domain;
using SqlSugar;
using Yitter.IdGenerator;

namespace OpenAuth.App.ServiceApp.AchievementManage;

/// <summary>
/// 成果管理
/// </summary>
public class AchievementManageApp : SqlSugarBaseApp<DroneFlyingTask, SugarDbContext>
{
    public AchievementManageApp(ISugarUnitOfWork<SugarDbContext> unitWork,
        ISimpleClient<DroneFlyingTask> repository, IAuth auth, FormSchemeApp formSchemeApp,
        IOptions<AppSetting> setOptions) : base(unitWork, repository, auth)
    {
    }

    //添加成果
    public Response<bool> AddImageexif(List<Imageexif> exifs)
    {
        using var client = Repository.AsSugarClient();

        var user = _auth.GetCurrentUser().User;
        var list = new List<DroneShpImageexif>();

        foreach (var item in exifs)
        {
            var model = item.MapTo<DroneShpImageexif>();
            model.Id = YitIdHelper.NextId();
            var coordinate = new Coordinate(item.Lng, item.Lat);
            //  model.Gemo = new Point(coordinate);
            model.UserId = user?.Id.ToString() ?? "";
            model.Name = user?.Name ?? "";
            model.TaskId = item.TaskId;
            list.Add(model);
        }

        var flag = client.Ado.UseTran(() =>
        {
            if (list.Count > 0)
            {
                var taskId = list.First().TaskId;

                client.Insertable(list).ExecuteCommand();
                client.Updateable<DroneFlyingTask>()
                    .SetColumns(a => a.ImageCount == a.ImageCount + list.Count)
                    .Where(a => a.Id == taskId)
                    .ExecuteCommand();
            }
        });

        if (flag.IsSuccess)
        {
            return new Response<bool> { Result = true };
        }
        else
        {
            return new Response<bool> { Result = false, Message = "操作失败" };
        }
    }

    /// <summary>
    /// 判读
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public async Task<Response<bool>> IntactById(long id)
    {
        using var client = Repository.AsSugarClient();
        var count = await client.Updateable<DroneShpImageexif>()
            .SetColumns(a => a.Intact == true)
            .Where(a => a.Id == id).ExecuteCommandAsync();
        if (count > 0)
        {
            return new Response<bool>() { Result = true, Message = "判读成功" };
        }
        else
        {
            return new Response<bool>() { Result = false, Message = "判读失败" };
        }
    }

    /// <summary>
    /// 添加任务
    /// </summary>
    /// <param name="task"></param>
    /// <returns></returns>
    public async Task<Response<bool>> AddTask()
    {
        using var client = Repository.AsSugarClient();
        await client.Ado.BeginTranAsync(IsolationLevel.ReadCommitted);
        var builder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json");
        // 构建配置
        var configuration = builder.Build();
        var imgDir = configuration["FlyImageDir"];
        // 获取所有子目录
        var dirInfo = new DirectoryInfo(imgDir);
        // 获取所有文件，包括子目录中的文件
        var files = dirInfo.GetFiles("MetaData.txt", SearchOption.AllDirectories);
        foreach (var file in files)
        {
            var meta = await File.ReadAllTextAsync(file.FullName);
            var obj = JsonConvert.DeserializeObject<JObject>(meta);
            var flyer = obj["peopleName"]?.ToString(); //无人机飞手
            var workPosition = obj["workPositon"]?.ToString(); //位置
            var imgCount = obj["imgCount"].ToInt(); //图片数量
            var flyTime = obj["timeDom"].ToDateTime(); // 航飞时间

            var dateDir = file.Directory?.Parent?.Name;
            var count = await client.Queryable<DroneFlyingTask>()
                .Where(a => a.WorkPosition.Equals(workPosition))
                .Where(a => a.TaskDate.Equals(dateDir))
                .CountAsync();
            if (count > 0)
            {
                continue;
            }

            var id = YitIdHelper.NextId();
            var task = new DroneFlyingTask
            {
                Id = id,
                TaskDate = dateDir,
                CreateTime = DateTime.Now,
                TaskName = workPosition + dateDir,
                ImageCount = imgCount,
                Flyer = flyer,
                FlyTime = flyTime,
                WorkPosition = workPosition
            };
            var effect = await client.Insertable(task).IgnoreColumnsNull().ExecuteCommandAsync();
            if (effect <= 0) throw new Exception("保存记录失败");
            var path = file.DirectoryName;
            if (string.IsNullOrEmpty(path))
            {
                throw new Exception("文件路径应包含日期/位置");
            }

            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            var posContent =
                await File.ReadAllLinesAsync(Path.Combine(path, "POS.txt"), Encoding.GetEncoding("gbk"));
            List<DroneShpImageexif> imageRecords = new List<DroneShpImageexif>(posContent.Length);
            foreach (var line in posContent)
            {
                // 郯城2-1.JPG,34.680657300,118.347714600,552.1300
                var el = line.Split(",");
                var fileName = el[0];
                var lng = double.Parse(el[2]);
                var lat = double.Parse(el[1]);
                // 图片全路径
                var imagePath = Path.Combine(path, fileName);
                //上传文件 
                var basePath = AppContext.BaseDirectory; // 项目运行目录
                var dirPath = DateTime.Now.ToString("yyyyMMdd");
                // 目标文件目录
                var uploadPath = Path.Combine(basePath, dirPath);
                if (!Directory.Exists(uploadPath))
                {
                    Directory.CreateDirectory(uploadPath);
                }

                var destinationFile = GenerateId.GenerateOrderNumber() + Path.GetExtension(imagePath).ToLower();
                // 路径 文件名 后缀名
                var destinationPath = Path.Combine(uploadPath, destinationFile);
                var accessUrlPart = Path.Combine(dirPath, destinationFile);
                File.Copy(imagePath, destinationPath, true);
                var fileRecord = new SysUploadFile
                {
                    Id = SnowFlakeSingle.instance.getID(),
                    FilePath = destinationPath,
                    FileName = fileName,
                    FileSize = file.Length.ToInt(),
                    CreateUserName = _auth.GetUserName(),
                    FileType = Path.GetExtension(fileName),
                    Extension = Path.GetExtension(fileName),
                    CreateTime = DateTime.Now,
                };
                client.Insertable(fileRecord);
                var image = new DroneShpImageexif
                {
                    UploadTime = DateTime.Now,
                    TaskName = workPosition + dateDir,
                    Id = YitIdHelper.NextId(),
                    TaskId = id,
                    Geometry = new Point(lng, lat),
                    Path = accessUrlPart,
                    WorkPosition = workPosition,
                    Flyer = flyer,
                    FlyTime = flyTime
                };
                imageRecords.Add(image);
            }

            int effectB = await client.Insertable(imageRecords).ExecuteCommandAsync();
            if (effectB == 0)
            {
                throw new Exception("保存失败");
            }
        }

        await client.Ado.CommitTranAsync();
        return new Response<bool> { Result = true, Message = "操作成功" };
    }

    /// <summary>
    /// 获取列表
    /// </summary>
    /// <param name="pageIndex"></param>
    /// <param name="pageSize"></param>
    /// <param name="taskName"></param>
    /// <param name="beginDate"></param>
    /// <param name="endDate"></param>
    /// <param name="createUser"></param>
    /// <returns></returns>
    public async Task<Response<PageInfo<List<TaskResp>>>> ListTask(int pageIndex, int pageSize, string taskName,
        string beginDate, string endDate, string createUser)
    {
        using var client = Repository.AsSugarClient();
        //返回值
        RefAsync<int> total = 0;
        var beginTime = Convert.ToDateTime(beginDate);
        var endTime = Convert.ToDateTime(endDate);

        var data = await client.Queryable<DroneFlyingTask>()
            .LeftJoin<SysUser>((a, u) => a.CreateUserId == u.Id.ToString())
            .WhereIF(!string.IsNullOrEmpty(taskName), (a) => a.TaskName.Contains(taskName))
            .WhereIF(!string.IsNullOrEmpty(beginDate), (a) => SqlFunc.Between(a.FlyTime, beginTime, endTime))
            .WhereIF(!string.IsNullOrEmpty(createUser), (a, u) => u.Name.Contains(createUser))
            .OrderByDescending(a => a.CreateTime)
            .Select((a, u) => new TaskResp
            {
                Id = a.Id,
                TaskName = a.TaskName,
                ImageCount = a.ImageCount,
                TaskDate = a.TaskDate,
                CreateTime = a.CreateTime,
                WorkPosition = a.WorkPosition,
                Flyer = a.Flyer,
                FlyTime = a.FlyTime
            }).ToPageListAsync(pageIndex, pageSize, total);
        // 遍历添加字段
        foreach (var taskResp in data)
        {
            var taskId = taskResp.Id;
            var query =
                @"SELECT ST_AsText(""Geometry"") as ""Geometry"" FROM drone_shp_imageexif where ""TaskId"" = " + taskId;
            taskResp.geometry = client.Ado.SqlQuery<string>(query).First();
        }

        return new Response<PageInfo<List<TaskResp>>>
        {
            Result = new PageInfo<List<TaskResp>>
            {
                Items = data,
                Total = total
            }
        };
    }

    /// <summary>
    /// 获取列表
    /// </summary>
    /// <param name="pageIndex"></param>
    /// <param name="pageSize"></param>
    /// <param name="taskName"></param>
    /// <param name="beginDate"></param>
    /// <param name="endDate"></param>
    /// <param name="createUser"></param>
    /// <returns></returns>
    public async Task<Response<PageInfo<List<DroneShpImageResp>>>> ListDroneShpImageexif(int pageIndex,
        int pageSize, long taskId, string beginDate, string endDate)
    {
        using var client = Repository.AsSugarClient();
        //返回值
        RefAsync<int> total = 0;
        var beginTime = Convert.ToDateTime(beginDate);
        var endTime = Convert.ToDateTime(endDate);
        // 原生SQL查询
        var query =
            @"SELECT ""Id"", ST_AsText(""Geometry"") as ""Geometry"",""Path"",""UploadTime"",""TaskId"",""WorkPosition"",""Flyer"",""FlyTime"",""TaskName""  FROM drone_shp_imageexif";

        // 执行查询并映射结果
        var entities = await client.SqlQueryable<DroneShpImageexif>(query)
            .WhereIF(taskId != 0, (t) => t.TaskId == taskId)
            .WhereIF(!string.IsNullOrEmpty(beginDate), (a) => SqlFunc.Between(a.UploadTime, beginTime, endTime))
            .OrderByDescending(t => t.UploadTime)
            .Select<DroneShpImageResp>(a => new DroneShpImageResp
            {
                Id = a.Id.SelectAll()
            })
            .ToPageListAsync(pageIndex, pageSize, total);

        return new Response<PageInfo<List<DroneShpImageResp>>>
        {
            Result = new PageInfo<List<DroneShpImageResp>>
            {
                Items = entities,
                Total = total
            }
        };
    }
}