using JLHHJSvr;
using JLHHJSvr.BLL;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;

namespace PhoneUI.BLL.L1BLL
{
    /// <summary>
    /// 获取用户filestring
    /// </summary>
    internal sealed class SysUserFileString : HelperBase
    {
        /// <summary>
        /// 获取用户自定义值
        /// </summary>
        /// <param name="empid">用户ID</param>
        /// <param name="dwname">窗口名</param>
        /// <param name="itemname">表格名</param>
        /// <param name="defaultvalue">默认值</param>
        /// <returns></returns>
        public string GetValue(int empid, string dwname, string itemname, string defaultvalue, bool compress = false)
        {
            try
            {
                cmd.CommandText = "SELECT itemvalue FROM sys_user_filestring WHERE empid = @empid AND dwname = @dwname AND itemname = @itemname";
                cmd.Parameters.Clear();
                cmd.Parameters.AddWithValue("@empid", empid);
                cmd.Parameters.AddWithValue("@dwname", dwname ?? string.Empty);
                cmd.Parameters.AddWithValue("@itemname", itemname ?? string.Empty);
                var val = string.Empty;
                using (var reader = cmd.ExecuteReader())
                {
                    if (!reader.Read())
                    {
                        return defaultvalue;
                    }

                    val = Convert.ToString(reader["itemvalue"]);
                }

                if (compress && !string.IsNullOrEmpty(val))
                {
                    val = Uncompress(val);
                }
                else if (val != null && val.StartsWith("H4sIAAAA"))
                {
                    val = Uncompress(val);
                    SetValue(empid, dwname, itemname, val);
                }
                return val;
            }
            catch (Exception ex)
            {
                Trace.Write(ex);
                return defaultvalue;
            }
        }

        /// <summary>
        /// 设置用户自定义值
        /// </summary>
        /// <param name="empid">用户ID</param>
        /// <param name="dwname">窗口名</param>
        /// <param name="itemname">表格名</param>
        /// <param name="strvalue">保存值</param>
        /// <returns></returns>
        public bool SetValue(int empid, string dwname, string itemname, string strvalue, bool compress = false)
        {
            try
            {
                var newvalue = strvalue;
                if (compress)
                {
                    newvalue = Compress(strvalue);
                }
                cmd.CommandText = "UPDATE sys_user_filestring SET itemvalue = @itemvalue WHERE empid = @empid AND dwname = @dwname AND itemname = @itemname";
                cmd.Parameters.Clear();
                cmd.Parameters.AddWithValue("@empid", empid);
                cmd.Parameters.AddWithValue("@dwname", dwname ?? string.Empty);
                cmd.Parameters.AddWithValue("@itemname", itemname ?? string.Empty);
                cmd.Parameters.AddWithValue("@itemvalue", newvalue);

                var nrows = cmd.ExecuteNonQuery();
                if (nrows == 0)
                {
                    cmd.CommandText = "INSERT INTO sys_user_filestring(empid, dwname, itemname, itemvalue) VALUES(@empid, @dwname, @itemname, @itemvalue)";
                    cmd.Parameters.Clear();
                    cmd.Parameters.AddWithValue("@empid", empid);
                    cmd.Parameters.AddWithValue("@dwname", dwname ?? string.Empty);
                    cmd.Parameters.AddWithValue("@itemname", itemname ?? string.Empty);
                    cmd.Parameters.AddWithValue("@itemvalue", newvalue);
                    cmd.ExecuteNonQuery();
                }
                return true;
            }
            catch (Exception ex)
            {
                Trace.Write(strvalue, "错误参数");
                Trace.Write(ex);
                return false;
            }
        }

        /// <summary>
        /// 获取用户窗口下的自定义键
        /// </summary>
        /// <param name="empid">用户ID</param>
        /// <param name="dwname">窗口名</param>
        /// <returns>键列表</returns>
        public List<string> GetItemnames(int empid, string dwname)
        {
            var rslt = new List<string>();
            try
            {
                cmd.CommandText = "SELECT itemname FROM sys_user_filestring WHERE empid = @empid AND dwname = @dwname ORDER BY itemname";
                cmd.Parameters.Clear();
                cmd.Parameters.AddWithValue("@empid", empid);
                cmd.Parameters.AddWithValue("@dwname", dwname);
                using (var reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        rslt.Add(Convert.ToString(reader["itemname"]).Trim());
                    }
                }
            }
            catch (Exception ex)
            {
                Trace.Write(ex);
            }
            return rslt;
        }

        /// <summary>
        /// 获取用户自定义值中,是否包含对应窗口名与表格名
        /// </summary>
        /// <param name="empid">用户ID</param>
        /// <param name="dwname">窗口名</param>
        /// <param name="itemname">表格名</param>
        /// <returns>是否存在</returns>
        public bool Exists(int empid, string dwname, string itemname)
        {
            try
            {
                cmd.CommandText = "SELECT COUNT(0) FROM sys_user_filestring WHERE empid = @empid AND dwname = @dwname AND itemname = @itemname";
                cmd.Parameters.Clear();
                cmd.Parameters.AddWithValue("@empid", empid);
                cmd.Parameters.AddWithValue("@dwname", dwname);
                cmd.Parameters.AddWithValue("@itemname", itemname);
                var cnt = Convert.ToInt32(cmd.ExecuteScalar());
                return cnt > 0;
            }
            catch (Exception ex)
            {
                Trace.Write(ex);
            }
            return false;
        }

        private static string Compress(string value)
        {
            using (var ms = new MemoryStream())
            using (var gzip = new GZipStream(ms, CompressionMode.Compress, true))
            using (var writer = new BinaryWriter(gzip))
            {
                writer.Write(value);
                writer.Flush();
                gzip.Close();
                var data = ms.ToArray();
                return Convert.ToBase64String(data);
            }
        }

        private static string Uncompress(string value)
        {
            var data = Convert.FromBase64String(value);
            using (var ms = new MemoryStream(data))
            using (var gzip = new GZipStream(ms, CompressionMode.Decompress, true))
            using (var reader = new BinaryReader(gzip))
            {
                return reader.ReadString();
            }
        }
        /// <summary>
        /// 当保存为系统方案的时候，删除所有其他人的布局方案
        /// </summary>
        public void delOtherLayout(string dwname, string itemname)
        {
            cmd.CommandText = @"delete sys_user_filestring where empid<>-1 and dwname = @dwname and  itemname = @itemname";
            cmd.Parameters.Clear();
            cmd.Parameters.AddWithValue("@dwname", dwname);
            cmd.Parameters.AddWithValue("@itemname", itemname);
            cmd.ExecuteNonQuery();
        }
        /// <summary>
        /// 删除某人的布局方案
        /// </summary>
        public void delLayout(int empid, string dwname, string itemname)
        {
            cmd.CommandText = @"delete sys_user_filestring where empid = @empid and dwname = @dwname and  itemname = @itemname";
            cmd.Parameters.Clear();
            cmd.Parameters.AddWithValue("@empid", empid);
            cmd.Parameters.AddWithValue("@dwname", dwname);
            cmd.Parameters.AddWithValue("@itemname", itemname);
            cmd.ExecuteNonQuery();
        }


        public void saveSystemLayout(string itemname, string itemvalue)
        {
            string rootPath;

            rootPath = Path.Combine(GlobalVar.DataPath, "UserFilestring");
#if DEBUG
            string basePath;
            int binIndex = GlobalVar.DataPath.IndexOf("\\bin\\", StringComparison.OrdinalIgnoreCase);
            if (binIndex == -1) throw new InvalidOperationException("DEBUG模式下未检测到bin目录路径结构");
            basePath = GlobalVar.DataPath.Substring(0, binIndex);

            rootPath = Path.Combine(basePath, "UserFilestring");
#endif
            if (!Directory.Exists(rootPath)) Directory.CreateDirectory(rootPath);

            var filePath = Path.Combine(rootPath, $"{itemname}.json");
            if (File.Exists(filePath))
            {
                File.Delete(filePath);
            }

            File.WriteAllText(filePath, itemvalue);
        }

        public string getSystemLayout(string dwname, string itemname, byte ifcompress)
        {
            string rootPath;
            string defaultRootPath;
            string result;

            rootPath = Path.Combine(GlobalVar.DataPath, "UserFilestring");
            defaultRootPath = Path.Combine(GlobalVar.DataPath, "DefaultLayout");
#if DEBUG
            string basePath;
            int binIndex = GlobalVar.DataPath.IndexOf("\\bin\\", StringComparison.OrdinalIgnoreCase);
            if (binIndex == -1) throw new InvalidOperationException("DEBUG模式下未检测到bin目录路径结构");
            basePath = GlobalVar.DataPath.Substring(0, binIndex);

            rootPath = Path.Combine(basePath, "BLL", "L1BLL", "UserFilestring");
            defaultRootPath = Path.Combine(basePath, "BLL", "L1BLL", "DefaultLayout");
#endif

            var filePath = Path.Combine(rootPath, $"{itemname}.json");
            var filePath_default = Path.Combine(defaultRootPath, $"{itemname}.json");
            if (File.Exists(filePath))
            {
                result = File.ReadAllText(filePath);
            } 
            else if (File.Exists(filePath_default))
            {
                result = File.ReadAllText(filePath_default);
            }
            else
            {
                result = GetValue(-1, dwname, itemname, string.Empty, ifcompress == 1 ? true : false);
            }

            return result;
        }

    }
}
