using System.Net;
using System.Net.Http.Headers;
using System.Text;
using System.Xml.Linq;
using DocumentFormat.OpenXml.Wordprocessing;
using Infrastructure;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OSGeo.GDAL;
using OSGeo.OSR;

namespace OpenAuth.App.ServiceApp.ShpGeo.Utils;

public class GeoUtil
{
    private static GeoContext _geoContext = GeoContext.Instance;

    // geosever 地址
    public static readonly string GeoserverUrl = _geoContext.GeoserverUrl;

    // 默认工作空间
    public static readonly string Workspace = _geoContext.Workspace;

    // geoserver 用户名
    public static readonly string Username = _geoContext.Username;

    // geoserver 密码
    public static readonly string Password = _geoContext.Password;

    // geosever 地址
    public static readonly string JobwebUrl = _geoContext.JobwebUrl;

    // 默认数据库 schema
    public static readonly string DbSchema = _geoContext.DbSchema;
    public static readonly string DbStoreName = _geoContext.DbStoreName;
    public static readonly string ConnectionString = _geoContext.ConnectionString;

    /// <summary>
    /// 创建数据存储和图层，样式存在的话，绑定样式
    /// </summary>
    /// <param name="srs"></param>
    /// <param name="layerName"></param>
    /// <param name="styleName"></param>
    public static async Task<bool> CreateStoreAndLayer(string workspace, string srs, string layerName, string styleName)
    {
        //{"PORT":"5432","Database":"drone_enforcement_linyi_20240712","HOST":"192.168.10.102","PASSWORD":"123456","USER ID":"postgres"}
        var dbElement = ParseConnectionString(ConnectionString);
        using var client = new HttpClient();
        var usernamePassword = Username + ":" + Password;
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));
        if (string.IsNullOrEmpty(workspace))
        {
            workspace = Workspace;
        }

        // 判断是否存在工作空间
        var existWorkspaceResponse = await ExistWorkspace(workspace);
        if (!existWorkspaceResponse.Result)
        {
            var createWorkspaceResponse = await CreateWorkspace(workspace);
            if (!createWorkspaceResponse.Result)
            {
                throw new Exception("创建工作空间失败");
            }
        }

        // 判断Db仓库是否存在
        var dbStoreExUrl = GeoserverUrl + "/rest/workspaces/" + workspace + "/datastores/" + DbStoreName + ".xml";
        var response = await client.GetAsync(dbStoreExUrl);
        if (response.StatusCode == HttpStatusCode.NotFound)
        {
            // 创建数据存储
            var contentStr = "<dataStore>" +
                             "<name>" + DbStoreName + "</name>" +
                             "<type>PostGIS</type>" +
                             "<enabled>true</enabled>" +
                             "<connectionParameters>" +
                             "<host>" + dbElement["HOST"] + "</host>" +
                             "<port>" + dbElement["PORT"] + "</port>" +
                             "<schema>" + DbSchema + "</schema>" +
                             "<database>" + dbElement["Database"] + "</database>" +
                             "<user>" + dbElement["USER ID"] + "</user>" +
                             "<passwd>" + dbElement["PASSWORD"] + "</passwd>" +
                             "<dbtype>postgis</dbtype>" +
                             //"<table>" + layerName + "</table>" +
                             "</connectionParameters>" +
                             "</dataStore>";

            var createDataStoreUrl = GeoserverUrl + "/rest/workspaces/" + workspace + "/datastores";
            var content = new StringContent(contentStr, Encoding.UTF8,
                "text/xml");
            // 执行创建数据存储
            var result = await client.PostAsync(createDataStoreUrl, content);
            var resultStr = result.Content.ReadAsStringAsync();
            // 未校验，一般失败就是已存在
            Console.WriteLine("创建数据存储StatusCode：" + result.StatusCode);
            Console.WriteLine("创建数据存储返回结果：" + resultStr.Result);
        }

        // 判断图层存不存在
        var layerExUrl = GeoserverUrl + "/rest/layers/" + workspace + ":" + layerName + ".xml";
        var layerExResult = await client.GetAsync(layerExUrl);
        if (layerExResult.StatusCode == HttpStatusCode.OK)
        {
            // 图层存在时间直接更新数据表即可
            return true;
            /*var deleteLayerUrl = GeoserverUrl + "/rest/layers/" + Workspace + ":" + layerName;
            var deleteLayerResult = await client.DeleteAsync(deleteLayerUrl);
            var deleteLayerResultStr = deleteLayerResult.Content.ReadAsStringAsync();
            Console.WriteLine("删除图层返回结果：" + deleteLayerResultStr.Result);
            if (deleteLayerResult.StatusCode != HttpStatusCode.OK)
            {
                throw new Exception("图层已存在但删除失败");
            }*/
            // 结束
        }

        //  创建图层1
        var createLayerUrl = GeoserverUrl + "/rest/workspaces/" + workspace + "/datastores/" + DbStoreName +
                             "/featuretypes";
        //  var createLayerUrl = GEOSERVER_URL + "/rest/workspaces/"+WORKSPACE+"layers";

        var createLayerContentStr = "<featureType>" +
                                    "<enabled>true</enabled>" +
                                    "<metadata />" +
                                    "<keywords />" +
                                    "<metadataLinks />" +
                                    "<attributes />" +
                                    "<title>" + layerName + "</title>" +
                                    "<name>" + layerName + "</name>" +
                                    "<srs>" + srs + "</srs>" +
                                    "<description>" + layerName + "</description>" +
                                    "</featureType>";
        Console.WriteLine("创建图层参数：" + createLayerContentStr);
        var createLayerContent = new StringContent(createLayerContentStr, Encoding.UTF8, "text/xml");
        var createLayerResult = await client.PostAsync(createLayerUrl, createLayerContent);
        var createLayerResultStr = createLayerResult.Content.ReadAsStringAsync();
        Console.WriteLine("创建图层返回code：" + createLayerResult.StatusCode);
        Console.WriteLine("创建图层返回结果：" + createLayerResultStr.Result);
        //  发布图层
        var publishLayerUrl = GeoserverUrl + "/rest/layers/" + workspace + ":" + layerName + "";
        var styleXmlPart = "";
        if (!string.IsNullOrEmpty(styleName))
        {
            styleXmlPart = "<defaultStyle>" +
                           "<name>" + styleName + "</name>" +
                           "<workspace>" + workspace + "</workspace>" +
                           "</defaultStyle>";
        }

        var publishContentStr =
            "<layer>" +
            "<enabled>true</enabled>" +
            "<styles />" +
            "<authorityURLs />" +
            "<identifiers />" +
            styleXmlPart +
            "</layer>";
        Console.WriteLine("发布图层参数：" + publishContentStr);
        var publishContent = new StringContent(publishContentStr, Encoding.UTF8, "text/xml");
        var publishLayerResult = await client.PutAsync(publishLayerUrl, publishContent);
        Console.WriteLine("发布图层返回结果：" + publishLayerResult.Content);
        if (publishLayerResult.StatusCode != HttpStatusCode.OK)
        {
            throw new Exception("发布图层失败");
        }

        return true;
    }

    /// <summary>
    /// 判断样式是否存在
    /// </summary>
    /// <param name="styleName"></param>
    /// <returns></returns>
    public static async Task<bool> ExistStyle(string workspace, string styleName)
    {
        using var client = new HttpClient();
        if (string.IsNullOrEmpty(workspace))
        {
            workspace = Workspace;
        }

        var usernamePassword = Username + ":" + Password;
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));

        var existStyleUrl = GeoserverUrl + "/rest/workspaces/" + workspace + "/styles/" +
                            styleName + ".xml";

        var response = await client.GetAsync(existStyleUrl);
        return response.StatusCode == HttpStatusCode.OK;
    }

    /// <summary>
    /// 创建SLD样式并发布
    /// </summary>
    /// <param name="sldPath"></param>
    /// <returns></returns>
    public static async Task<bool> PublishSldStyle(string sldPath, string styleName)
    {
        using var client = new HttpClient();
        var usernamePassword = Username + ":" + Password;
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));

        // 样式名称
        var sldFileName = Path.GetFileName(sldPath);
        //var styleName = Path.GetFileNameWithoutExtension(sldPath);

        // todo 判断样式是否存在 
        // 如何存在更新样式
        //string apiUrl = GEOSERVER_URL +  "/rest/styles?format=json&namespace=default&type=style&name={styleName}";

        // 发布SLD样式两步骤 curl -v -u admin:geoserver -XPOST -H "Content-type: text/xml" -d "<style><name>roads_style</name><filename>roads.sld</filename></style>" http://localhost:8080/geoserver/rest/styles
        var prePublicSld = GeoserverUrl + "/rest/workspaces/" + Workspace + "/styles";
        // "<style><name>roads_style</name><filename>roads.sld</filename></style>"
        var prePublishSldXml = "<style><name>" + styleName + "</name><filename>" + sldFileName + "</filename></style>";

        var response = await client.PostAsync(prePublicSld,
            new StringContent(prePublishSldXml, Encoding.UTF8, "text/xml"));

        if (response.StatusCode == HttpStatusCode.Created)
        {
            Console.WriteLine("SLD样式预发布返回结果：" + response.Content.ReadAsStringAsync().Result);
            // 发布SLD样式第二步 
            // curl -v -u admin:geoserver -XPUT -H "Content-type: application/vnd.ogc.sld+xml" -d @roads.sld http://localhost:8080/geoserver/rest/styles/roads_style
            //var publishSldToWorkspaceUrl = GeoserverUrl + "/rest/workspaces/" + Workspace + "/styles?name=" + Uri.EscapeDataString(styleName);
            var publishSldToWorkspaceUrl = GeoserverUrl + "/rest/workspaces/" + Workspace + "/styles/" + styleName;

            // SLD文件内容
            var sldContent = await File.ReadAllTextAsync(sldPath, Encoding.UTF8);
            // 创建请求
            var content = new StringContent(sldContent, Encoding.UTF8,
                "application/vnd.ogc.sld+xml");
            // 执行创建数据存储
            response = await client.PutAsync(publishSldToWorkspaceUrl, content);
            // 检查响应
            Console.WriteLine(response.StatusCode);
            Console.WriteLine("SLD样式发布返回结果：" + response.Content.ReadAsStringAsync().Result);
            if (response.StatusCode == HttpStatusCode.OK)
            {
                Console.WriteLine("SLD发布成功");
                return true;
            }
        }
        else
        {
            Console.WriteLine("SLD图层已存在");
            return false;
        }

        Console.WriteLine($"SLD发布失败，状态码：{response.StatusCode}");
        return false;
    }

    // # 创建工作区（如果不存在）
    //curl -u $USERNAME:$PASSWORD -X POST -H "Content-type: text/xml" -d "<workspace><name>$WORKSPACE</name></workspace>" $GEOSERVER_URL/rest/workspaces
    /// <summary>
    /// 解析数据库连接字符串
    /// </summary>
    /// <param name="connectionString"></param>
    /// <returns></returns>
    static Dictionary<string, string> ParseConnectionString(string connectionString)
    {
        var details = new Dictionary<string, string>();
        var parts = connectionString.Split(';');

        foreach (var part in parts)
        {
            var index = part.IndexOf('=');
            if (index != -1)
            {
                var key = part.Substring(0, index);
                var value = part.Substring(index + 1);
                details[key] = value;
            }
        }

        return details;
    }

    /// <summary>
    ///  获取图层bbox
    /// </summary>
    /// <param name="workspace"></param>
    /// <param name="storeName"></param>
    /// <param name="layerName"></param>
    /// <returns></returns>
    public static async Task<Response<string>> GetDBLayerBBox(string workspace, string storeName, string layerName)
    {
        using var client = new HttpClient();
        var usernamePassword = Username + ":" + Password;
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));
        if (string.IsNullOrEmpty(workspace))
        {
            workspace = Workspace;
        }

        var dbStoreExUrl =
            $"{GeoserverUrl}/rest/workspaces/{workspace}/datastores/{storeName}/featuretypes/{layerName}.json";
        var dbStoreExResult = await client.GetAsync(dbStoreExUrl);
        var resultObj = JsonConvert.DeserializeObject<JObject>(dbStoreExResult.Content.ReadAsStringAsync().Result);
        if (dbStoreExResult.StatusCode == HttpStatusCode.OK)
        {
            var bbox = resultObj["featureType"]["latLonBoundingBox"];
            var minx = bbox["minx"];
            var miny = bbox["miny"];
            var maxx = bbox["maxx"];
            var maxy = bbox["maxy"];
            Console.WriteLine("minx:" + minx);
            Console.WriteLine("miny:" + miny);
            Console.WriteLine("maxx:" + maxx);
            Console.WriteLine("maxy:" + maxy);
            Console.WriteLine("信息：" + dbStoreExResult.Content.ReadAsStringAsync().Result);
            return new Response<string>
            {
                Result = minx + "," + miny + "," + maxx + "," + maxy,
                Code = 200
            };
        }

        return new Response<string>
        {
            Code = 500
        };
    }

    /// <summary>
    ///  取得bbox 及 srs 信息
    /// </summary>
    /// <param name="workspace">工作空间名称</param>
    /// <param name="storeName">存储仓库名称</param>
    /// <param name="layerName">图层名称</param>
    /// <returns></returns>
    public static async Task<Response<dynamic>> GetTiffLayerInfo(string workspace, string storeName, string layerName)
    {
        using var client = new HttpClient();
        var usernamePassword = Username + ":" + Password;
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));

        if (string.IsNullOrEmpty(workspace))
        {
            workspace = Workspace;
        }

        var dbStoreExUrl =
            $"{GeoserverUrl}/rest/workspaces/{workspace}/coveragestores/{storeName}/coverages/{layerName}.json";
        var dbStoreExResult = await client.GetAsync(dbStoreExUrl);
        if (dbStoreExResult.StatusCode == HttpStatusCode.OK)
        {
            var resultObj = JsonConvert.DeserializeObject<JObject>(dbStoreExResult.Content.ReadAsStringAsync().Result);
            Console.WriteLine("GetTiffLayerInfo信息：" + dbStoreExResult.Content.ReadAsStringAsync().Result);
            var bbox = resultObj["coverage"]?["nativeBoundingBox"];
            var srs = resultObj["coverage"]?["srs"];
            var minx = bbox["minx"];
            var miny = bbox["miny"];
            var maxx = bbox["maxx"];
            var maxy = bbox["maxy"];
            Console.WriteLine("minx:" + minx);
            Console.WriteLine("miny:" + miny);
            Console.WriteLine("maxx:" + maxx);
            Console.WriteLine("maxy:" + maxy);
            return new Response<dynamic>
            {
                Result = new { bbox = minx + "," + miny + "," + maxx + "," + maxy, srs = srs },
                Code = 200
            };
        }

        return new Response<dynamic>
        {
            Code = 500,
            Message = dbStoreExResult.Content.ReadAsStringAsync().Result
        };
    }

    /// <summary>
    /// 删除栅格仓库
    /// </summary>
    /// <param name="workspace"></param>
    /// <param name="storeName"></param>
    /// <param name="recurse">递归删除（true 仓库下所有资源都将被删除）</param>
    /// <returns></returns>
    public static async Task<Response<bool>> DeleteCoveragesStore(string workspace, string storeName,
        bool recurse = false)
    {
        using var client = new HttpClient();
        var usernamePassword = Username + ":" + Password;
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));

        if (string.IsNullOrEmpty(workspace))
        {
            workspace = Workspace;
        }

        // 删除 coverageStore
        // The recurse controls recursive deletion. When set to true all resources contained in the store are also removed. The default value is "false".
        var deleteTiffStoreUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}/coveragestores/{storeName}";
        if (recurse)
        {
            deleteTiffStoreUrl += "?recurse=true";
        }
        else
        {
            deleteTiffStoreUrl += "?recurse=false";
        }

        var deleteTiffStoreResult = await client.DeleteAsync(deleteTiffStoreUrl);
        Console.WriteLine("删除栅格仓库");
        Console.WriteLine(deleteTiffStoreResult.Content.ReadAsStringAsync().Result);
        Console.WriteLine(deleteTiffStoreResult.StatusCode);
        switch (deleteTiffStoreResult.StatusCode)
        {
            case HttpStatusCode.OK:
                return new Response<bool>
                {
                    Result = true,
                    Code = 200
                };
            case HttpStatusCode.NotFound:
                return new Response<bool>
                {
                    Result = false,
                    Code = 404
                };
            default:
                return new Response<bool>
                {
                    Result = false,
                    Code = 500,
                    Message = deleteTiffStoreResult.Content.ReadAsStringAsync().Result
                };
        }
    }

    /// <summary>
    /// 删除图层
    /// </summary>
    /// <param name="workspace">工作空间，可不填</param>
    /// <param name="layerName"></param>
    /// <returns></returns>
    public static async Task<Response<bool>> DeleteLayer(string workspace, string layerName)
    {
        using var client = new HttpClient();
        var usernamePassword = Username + ":" + Password;
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));

        if (string.IsNullOrEmpty(workspace))
        {
            workspace = Workspace;
        }

        var deleteLayerUrl = $"{GeoserverUrl}/rest/layers/{workspace}:{layerName}";
        var deleteLayerResponse = await client.DeleteAsync(deleteLayerUrl);
        Console.WriteLine("删除图层返回结果：");
        Console.WriteLine(deleteLayerResponse.Content.ReadAsStringAsync().Result);
        Console.WriteLine(deleteLayerResponse.StatusCode);
        if (deleteLayerResponse.StatusCode == HttpStatusCode.OK)
        {
            return new Response<bool>
            {
                Result = true,
                Code = 200
            };
        }

        return new Response<bool>
        {
            Result = false,
            Code = 500
        };
    }

    /// <summary>
    /// 发布GeoTiff
    /// </summary>
    /// <param name="workspace"></param>
    /// <param name="tifFullName">tif文件全路径</param>
    /// <param name="storeName">栅格仓库名称</param>
    /// <param name="layerName">图层名称</param>
    /// <returns></returns>
    public static async Task<Response<bool>> PublishExternalGeoTIFF(string workspace, string tifFullName,
        string storeName, string layerName)
    {
        var srs = "4548";
        Console.WriteLine("传入影像全路径:" + tifFullName);
        /*var tifCrs = GetTifCrs(tifFullName);
        if (tifCrs.srs != null)
        {
            srs = tifCrs.srs;
        }*/

        if (string.IsNullOrEmpty(tifFullName) || string.IsNullOrEmpty(storeName) || string.IsNullOrEmpty(layerName))
        {
            return new Response<bool>
            {
                Result = false,
                Message = "参数不能为空"
            };
        }

        using var client = new HttpClient();
        var usernamePassword = Username + ":" + Password;
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));

        if (string.IsNullOrEmpty(workspace))
        {
            workspace = Workspace;
        }

        var existWorkspaceResponse = await ExistWorkspace(workspace);
        if (!existWorkspaceResponse.Result)
        {
            var createWorkspaceResponse = await CreateWorkspace(workspace);
            if (!createWorkspaceResponse.Result)
            {
                throw new Exception("创建工作空间失败,请检查geoserver状态");
            }
        }

        // 创建 coverageStore
        var createTiffStoreUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}/coveragestores";
        var tiffXml = $"<coverageStore>" +
                      $"<name>{storeName}</name><workspace>{workspace}</workspace>" +
                      "<enabled>true</enabled>" +
                      "<type>GeoTIFF</type>" +
                      $"<url>file://{tifFullName}</url>" +
                      "</coverageStore>";
        //Console.WriteLine("栅格仓库xml: " + tiffXml);
        //GeoUtil.DeleteCoveragesStore(workspace, storeName, false);
        var content = new StringContent(tiffXml, Encoding.UTF8, "application/xml");
        var response = await client.PostAsync(createTiffStoreUrl, content);
        if (response.StatusCode != HttpStatusCode.Created)
        {
            var msg = await response.Content.ReadAsStringAsync();
            Console.Write("创建栅格仓库code: " + response.StatusCode + "错误信息：" + msg);
            return new Response<bool>
            {
                Result = false,
                Message = "创建仓库失败：" + msg
            };
        }

        // 创建coverages
        var createTiffCoveragesUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}/coveragestores/{storeName}/coverages";

        var tiffFileName = Path.GetFileNameWithoutExtension(tifFullName);
        // nativeName 参数必须是tiff文件名称
        var createTiffCoveragesXml = @$"<coverage>
                               <nativeName>{storeName}</nativeName>
            <nativeCoverageName>{tiffFileName}</nativeCoverageName>
                                     <enabled>true</enabled>
                                     <metadata />
                                     <keywords />
                                     <metadataLinks />
                                     <name>{layerName}</name>
                                     <title>{layerName}</title>
                                     <srs>EPSG:{srs}</srs><projectionPolicy>REPROJECT_TO_DECLARED</projectionPolicy>
                                     <parameters>
                                        <entry>
                                            <string>InputTransparentColor</string>
                                            <string>#000000</string>
                                        </entry>
                                     </parameters>
                                     </coverage>";
        var createTiffCoveragesContent =
            new StringContent(createTiffCoveragesXml, Encoding.UTF8, "text/xml");
        var createTiffCoveragesResponse = await client.PostAsync(createTiffCoveragesUrl, createTiffCoveragesContent);
        if (createTiffCoveragesResponse.StatusCode != HttpStatusCode.Created)
        {
            var msg = await createTiffCoveragesResponse.Content.ReadAsStringAsync();
            //Console.Write(createTiffCoveragesResponse.StatusCode + " ");
            //Console.WriteLine(msg);
            return new Response<bool>
            {
                Result = false,
                Message = "创建仓库失败：" + msg
            };
        }

        var publishTiffLayerUrl =
            $"{GeoserverUrl}/rest/layers/{workspace}:{layerName}";
        var publishTiffLayerXml = "<layer><enabled>true</enabled></layer>";
        var publishTiffLayerContent = new StringContent(publishTiffLayerXml, Encoding.UTF8, "text/xml");
        var publishTiffLayerResponse = await client.PutAsync(publishTiffLayerUrl, publishTiffLayerContent);
        if (publishTiffLayerResponse.StatusCode != HttpStatusCode.OK)
        {
            var msg = await publishTiffLayerResponse.Content.ReadAsStringAsync();
            //Console.Write(publishTiffLayerResponse.StatusCode + " ");
            //Console.WriteLine(msg);
            return new Response<bool>
            {
                Result = false,
                Message = "发布图层失败：" + msg
            };
        }

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

    /// <summary>
    /// 判断工作空间是否存在
    /// </summary>
    /// <param name="workspace"></param>
    /// <returns></returns>
    public static async Task<Response<bool>> ExistWorkspace(string workspace)
    {
        using var client = new HttpClient();
        var usernamePassword = Username + ":" + Password;
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));

        var url = $"{GeoserverUrl}/rest/workspaces/{workspace}.xml";
        var response = await client.GetAsync(url);
        Console.WriteLine($"状态码：{response.StatusCode} 返回结果：{response.Content.ReadAsStringAsync().Result}");
        if (response.StatusCode == HttpStatusCode.NotFound)
        {
            return new Response<bool>
            {
                Result = false
            };
        }

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

    /// <summary>
    /// 创建工作空间
    /// </summary>
    /// <param name="workspace"></param>
    /// <returns></returns>
    public static async Task<Response<bool>> CreateWorkspace(string workspace)
    {
        using var client = new HttpClient();
        var usernamePassword = Username + ":" + Password;
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));

        var createWorkspaceUrl = $"{GeoserverUrl}/rest/workspaces";
        var createWorkspaceXml = $"<workspace><name>{workspace}</name></workspace>";
        var createWorkspaceContent = new StringContent(createWorkspaceXml, Encoding.UTF8, "text/xml");
        var createWorkspaceResponse = await client.PostAsync(createWorkspaceUrl, createWorkspaceContent);
        if (createWorkspaceResponse.StatusCode == HttpStatusCode.Created)
        {
            return new Response<bool>
            {
                Result = true
            };
        }

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


    /// <summary>
    /// 删除工作空间
    /// </summary>
    /// <param name="workspace"></param>
    /// <returns></returns>
    public static async Task<Response<bool>> DeleteWorkspace(string workspace)
    {
        using var client = new HttpClient();
        var usernamePassword = Username + ":" + Password;
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));

        var deleteWorkspaceUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}" + "?recurse=true";
        var deleteWorkspaceResponse = await client.DeleteAsync(deleteWorkspaceUrl);
        Console.WriteLine("删除工作空间返回结果：");
        Console.WriteLine(deleteWorkspaceResponse.Content.ReadAsStringAsync().Result);
        Console.WriteLine(deleteWorkspaceResponse.StatusCode);
        if (deleteWorkspaceResponse.StatusCode == HttpStatusCode.OK)
        {
            return new Response<bool>
            {
                Result = true,
                Code = 200
            };
        }

        return new Response<bool>
        {
            Result = false,
            Code = 500
        };
    }


    public static async Task<Response<bool>> SettingLayerReturnFormat(string workspace, string layerName)
    {
        using var client = new HttpClient();

        if (string.IsNullOrEmpty(workspace))
        {
            workspace = Workspace;
        }

        var usernamePassword = Username + ":" + Password;
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));


        var queryLayerUrl = GeoserverUrl + "/gwc/rest/layers/" + workspace + ":" + layerName + ".xml";
        var queryResult = await client.GetAsync(queryLayerUrl);
        Console.WriteLine(
            $" 结果：{queryResult.Content.ReadAsStringAsync().Result} code: {queryResult.StatusCode}");
        if (queryResult.StatusCode == HttpStatusCode.OK)
        {
            var split = queryResult.Content.ReadAsStringAsync().Result.Split("<mimeFormats>");
            var xml = split[0] + "<mimeFormats>" +
                      "<string>application/json;type=geojson</string>" +
                      "<string>application/json;type=topojson</string>" +
                      "<string>application/vnd.mapbox-vector-tile</string>" +
                      "<string>application/json;type=utfgrid</string>" +
                      split[1];
            var setGwc = GeoserverUrl + "/gwc/rest/layers/" + workspace + ":" + layerName;
            var content = new StringContent(xml, Encoding.UTF8,
                "application/xml");
            var result = await client.PostAsync(setGwc, content);
            if (result.StatusCode == HttpStatusCode.OK)
            {
                return new Response<bool>()
                {
                    Result = true,
                    Code = 200
                };
            }
        }

        return new Response<bool>
        {
            Result = false,
            Code = 500
        };
    }

    /// <summary>
    /// 更新样式名，更新样式
    /// </summary>
    /// <param name="sldPath"></param>
    /// <param name="styleName"></param>
    /// <returns></returns>
    public static async Task<bool> UpdateSldStyle(string sldPath, string styleName)
    {
        using var client = new HttpClient();
        var usernamePassword = Username + ":" + Password;
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));

        var publishSldToWorkspaceUrl = GeoserverUrl + "/rest/workspaces/" + Workspace + "/styles/" + styleName;
        // SLD文件内容
        var sldContent = await File.ReadAllTextAsync(sldPath, Encoding.UTF8);
        // 创建请求
        var content = new StringContent(sldContent, Encoding.UTF8,
            "application/vnd.ogc.sld+xml");
        // 执行创建数据存储
        var response = await client.PutAsync(publishSldToWorkspaceUrl, content);
        // 检查响应
        Console.WriteLine(response.StatusCode);
        Console.WriteLine("SLD样式发布返回结果：" + response.Content.ReadAsStringAsync().Result);
        if (response.StatusCode == HttpStatusCode.OK)
        {
            Console.WriteLine("SLD发布成功");
            return true;
        }

        return false;
    }

    public static async Task<Response<bool>> UpdateStyle(string workspace, string layerName, string styleName)
    {
        using var client = new HttpClient();
        var usernamePassword = Username + ":" + Password;
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));

        if (string.IsNullOrEmpty(workspace))
        {
            workspace = Workspace;
        }

        var url = $"{GeoserverUrl}/rest/layers/{workspace}:{layerName}.xml";
        //var xml = $"<layer><defaultStyle><name>{styleName}</name></defaultStyle></layer>";
        var xml = $@"
            <layer>
                <defaultStyle>
                    <name>{styleName}</name>
                </defaultStyle>
            </layer>";
        var content = new StringContent(xml, Encoding.UTF8,
            "application/xml");
        var result = await client.PutAsync(url, content);
        if (result.StatusCode == HttpStatusCode.OK)
        {
            return new Response<bool>
            {
                Result = true,
            };
        }

        return new Response<bool>
        {
            Result = false,
            Code = 500
        };
    }

    public static async Task<Response<bool>> publishLayerGroup(string workspace, string layers, string layerGroupName)
    {
        using var client = new HttpClient();
        var usernamePassword = Username + ":" + Password;
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));

        if (string.IsNullOrEmpty(workspace))
        {
            workspace = Workspace;
        }

        var url = $"{GeoserverUrl}/rest/workspaces/{workspace}/layergroups";
        var xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
                  "<layerGroup>" +
                  "  <name>" + layerGroupName + "</name>" +
                  "  <title>" + layerGroupName + "</title>" +
                  "  <workspace>" +
                  "    <name>" + workspace + "</name>" +
                  "  </workspace>" +
                  "  <layers>" +
                  layers +
                  "  </layers>" +
                  "</layerGroup>";
        var content = new StringContent(xml, Encoding.UTF8,
            "text/xml");
        var result = await client.PostAsync(url, content);
        if (result.StatusCode == HttpStatusCode.OK)
        {
            return new Response<bool>
            {
                Result = true,
            };
        }

        return new Response<bool>
        {
            Result = false,
            Code = 500
        };
    }

    /// <summary>
    /// 发布GeoTiff
    /// </summary>
    /// <param name="workspace"></param>
    /// <param name="tifFullName">tif文件全路径</param>
    /// <param name="storeName">栅格仓库名称</param>
    /// <param name="layerName">图层名称</param>
    /// <returns></returns>
    public static async Task<Response<bool>> PublishSingleGeoTIFF(string workspace, string tifFullName,
        string storeName, string layerName)
    {
        if (string.IsNullOrEmpty(tifFullName) || string.IsNullOrEmpty(storeName) || string.IsNullOrEmpty(layerName))
        {
            return new Response<bool>
            {
                Result = false,
                Message = "参数不能为空"
            };
        }

        using var client = new HttpClient();
        var usernamePassword = Username + ":" + Password;
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));

        if (string.IsNullOrEmpty(workspace))
        {
            workspace = Workspace;
        }

        var existWorkspaceResponse = await ExistWorkspace(workspace);
        if (!existWorkspaceResponse.Result)
        {
            var createWorkspaceResponse = await CreateWorkspace(workspace);
            if (!createWorkspaceResponse.Result)
            {
                throw new Exception("创建工作空间失败,请检查geoserver状态");
            }
        }

        // 创建 coverageStore
        var createTiffStoreUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}/coveragestores";
        var tiffXml = $"<coverageStore>" +
                      $"<name>{storeName}</name><workspace>{workspace}</workspace>" +
                      "<enabled>true</enabled>" +
                      "<type>GeoTIFF</type>" +
                      $"<url>file://{tifFullName}</url>" +
                      "</coverageStore>";
        //Console.WriteLine("栅格仓库xml: " + tiffXml);
        //GeoUtil.DeleteCoveragesStore(workspace, storeName, false);
        var content = new StringContent(tiffXml, Encoding.UTF8, "application/xml");
        var response = await client.PostAsync(createTiffStoreUrl, content);
        if (response.StatusCode != HttpStatusCode.Created)
        {
            var msg = await response.Content.ReadAsStringAsync();
            Console.Write("创建栅格仓库code: " + response.StatusCode + "错误信息：" + msg);
            return new Response<bool>
            {
                Result = false,
                Message = "创建仓库失败：" + msg
            };
        }

        // 创建coverages
        var createTiffCoveragesUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}/coveragestores/{storeName}/coverages";

        var tiffFileName = Path.GetFileName(tifFullName).Replace(Path.GetExtension(tifFullName), "");
        // nativeName 参数必须是tiff文件名称
        var createTiffCoveragesXml = @$"<coverage>
                        
                                     <enabled>true</enabled>
                                     <metadata />
                                     <keywords />
                                     <metadataLinks />
                                     <name>{layerName}</name>
                                     <title>{layerName}</title>
                                     <srs>EPSG:4548</srs><projectionPolicy>REPROJECT_TO_DECLARED</projectionPolicy>
                                 
                                     </coverage>";
        var createTiffCoveragesContent =
            new StringContent(createTiffCoveragesXml, Encoding.UTF8, "text/xml");
        var createTiffCoveragesResponse = await client.PostAsync(createTiffCoveragesUrl, createTiffCoveragesContent);
        if (createTiffCoveragesResponse.StatusCode != HttpStatusCode.Created)
        {
            var msg = await createTiffCoveragesResponse.Content.ReadAsStringAsync();
            Console.Write(createTiffCoveragesResponse.StatusCode + " ");
            Console.WriteLine(msg);
            return new Response<bool>
            {
                Result = false,
                Message = "创建仓库失败：" + msg
            };
        }

        var publishTiffLayerUrl =
            $"{GeoserverUrl}/rest/layers/{workspace}:{layerName}";
        var publishTiffLayerXml = "<layer><enabled>true</enabled></layer>";
        var publishTiffLayerContent = new StringContent(publishTiffLayerXml, Encoding.UTF8, "text/xml");
        var publishTiffLayerResponse = await client.PutAsync(publishTiffLayerUrl, publishTiffLayerContent);
        if (publishTiffLayerResponse.StatusCode != HttpStatusCode.OK)
        {
            var msg = await publishTiffLayerResponse.Content.ReadAsStringAsync();
            Console.Write(publishTiffLayerResponse.StatusCode + " ");
            Console.WriteLine(msg);
            return new Response<bool>
            {
                Result = false,
                Message = "发布图层失败：" + msg
            };
        }

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

    public static async Task<string> GetTiffLayerInfo1(string workspace, string storeName, string layerName)
    {
        using var client = new HttpClient();
        var usernamePassword = Username + ":" + Password;
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));

        if (string.IsNullOrEmpty(workspace))
        {
            workspace = Workspace;
        }

        var dbStoreExUrl =
            $"{GeoserverUrl}/rest/workspaces/{workspace}/coveragestores/{storeName}/coverages/{layerName}.json";
        var dbStoreExResult = await client.GetAsync(dbStoreExUrl);
        if (dbStoreExResult.StatusCode == HttpStatusCode.OK)
        {
            var resultObj = JsonConvert.DeserializeObject<JObject>(dbStoreExResult.Content.ReadAsStringAsync().Result);
            return JsonConvert.SerializeObject(resultObj);
        }

        return "执行失败";
    }

    /// <summary>
    /// 查询图层组是否存在
    /// </summary>
    /// <param name="workspace">工作空间名称</param>
    /// <param name="layerGroupName">图层组名称</param>
    /// <returns>图层组是否存在</returns>
    public static async Task<bool> ExistLayerGroup(string workspace, string layerGroupName)
    {
        using var client = new HttpClient();
        var usernamePassword = Username + ":" + Password;
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));

        if (string.IsNullOrEmpty(workspace))
        {
            workspace = Workspace; // 如果没有指定工作空间，默认使用 "default"
        }

        var existLayerGroupUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}/layergroups/{layerGroupName}.json";

        var response = await client.GetAsync(existLayerGroupUrl);
        return response.StatusCode == HttpStatusCode.OK;
    }

    /// <summary>
    /// 向图层组中添加图层
    /// </summary>
    /// <param name="workspace">工作空间名称</param>
    /// <param name="layerGroupName">图层组名称</param>
    /// <param name="layerNames">要添加的图层名称列表</param>
    /// <returns>操作是否成功</returns>
    public static async Task<bool> AddLayersToLayerGroup(string workspace, string layerGroupName,
        List<string> layerNames)
    {
        using var client = new HttpClient();
        var usernamePassword = Username + ":" + Password;
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));

        if (string.IsNullOrEmpty(workspace))
        {
            workspace = Workspace; // 如果没有指定工作空间
        }

        var addLayersUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}/layergroups/{layerGroupName}.xml";
        var groupResponse = client.GetAsync(addLayersUrl).Result.Content.ReadAsStringAsync();
        var existingLayers = XDocument.Parse(groupResponse.Result).Descendants("publishables").Descendants("published")
            .Descendants("name").Select(l => l.Value).ToList();
        var layersXml = string.Join("",
            layerNames.Select(layerName => $"<layer>{workspace}:{layerName}</layer>")
                .Union(existingLayers.Select(x => $"<layer>{x}</layer>")).Distinct());
        layerNames.AddRange(existingLayers);
        //var stylesXml = string.Join("", layerNames.Select(layerName => "<style><name>default</name></style>"));

        // todo 发布图层组
        var url = $"{GeoserverUrl}/rest/workspaces/{workspace}/layergroups";
        var xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
                  "<layerGroup>" +
                  "  <name>" + layerGroupName + "</name>" +
                  "  <title>" + layerGroupName + "</title>" +
                  "  <workspace>" +
                  "    <name>" + workspace + "</name>" +
                  "  </workspace>" +
                  "  <layers>" +
                  layersXml +
                  "  </layers>" +
                  "</layerGroup>";
        var content = new StringContent(xml, Encoding.UTF8,
            "text/xml");
        var result = await client.PostAsync(url, content);
        return result.IsSuccessStatusCode;
        ;
        /*const string fixedBbox =
            "117.34046403513817,34.331716698906675,119.27763051149853,36.263686454243626";
        var requestBody = $@"
            <layerGroup>
                <name>{layerGroupName}</name>
                <workspace>
                    <name>{workspace}</name>
                </workspace>
                <title>{layerGroupName}</title>
                <layers>
                    {layersXml}
                </layers>
                <bounds>
                    <minx>{fixedBbox.Split(',')[0]}</minx>
                    <miny>{fixedBbox.Split(',')[1]}</miny>
                    <maxx>{fixedBbox.Split(',')[2]}</maxx>
                    <maxy>{fixedBbox.Split(',')[3]}</maxy>
                    <crs>EPSG:4326</crs>
                </bounds>
                <styles>
                    {stylesXml}
                </styles>
            </layerGroup>";
        var content = new StringContent(requestBody, Encoding.UTF8, "text/xml");
        // 发送 PUT 请求
        var response = await client.PutAsync(addLayersUrl, content);
        // 检查响应状态码
        return response.IsSuccessStatusCode;*/
    }

    public static dynamic GetTifCrs(string filePath)
    {
        GdalConfiguration.ConfigureGdal();
        GdalConfiguration.ConfigureOgr(); //矢量
        GdalConfiguration.ConfigureOgr();
        // 初始化 GDAL
        Gdal.AllRegister();

        // 打开 TIFF 文件
        //string filePath = "C:/ChengGuoFinal/tiff/无人机巡飞影像数据/20240713/兰山区/20240713兰山区马厂湖_0.2.tif.aux_更新.tif";
        Dataset dataset = Gdal.Open(filePath, Access.GA_ReadOnly);

        if (dataset == null)
        {
            Console.WriteLine("无法打开 TIFF 文件");
            throw new Exception("无法打开 TIFF 文件");
        }

        // 获取投影信息
        string projection = dataset.GetProjection();
        var x = dataset.GetProjectionRef();
        if (!string.IsNullOrEmpty(projection))
        {
            Console.WriteLine("投影信息:");
            Console.WriteLine(projection);
        }
        else
        {
            Console.WriteLine("无法获取投影信息");
        }

        // 获取空间参照信息
        SpatialReference srs = dataset.GetSpatialRef();
        Console.WriteLine("空间参照信息:");
        // 解析EPSG代码
        // 如果没有EPSG代码，可以尝试其他方法获取
        var epsgCode = srs.GetAuthorityCode(null);
        Console.WriteLine($"EPSG代码: {epsgCode}");
        // 关闭数据集
        dataset.Dispose();
        dynamic obj = new System.Dynamic.ExpandoObject();
        obj.projection = projection;
        obj.srs = epsgCode;
        return obj;
    }
}