using System.IO;
using System.Text;

namespace SHH.CameraDashboard
{
    /// <summary>
    /// 本地文件存储服务
    /// 职责：
    /// 1.  提供通用的、异步的对象序列化和反序列化功能。
    /// 2.  将对象保存为 UTF-8 编码的 JSON 文件。
    /// 3.  从 JSON 文件中读取并反序列化为对象。
    /// 4.  处理文件不存在、内容为空或格式错误等常见异常情况。
    /// </summary>
    public static class LocalStorageService
    {
        #region --- 保存方法 ---

        /// <summary>
        /// 将指定对象异步保存到文件。
        /// </summary>
        /// <typeparam name="T">要保存的对象的类型。</typeparam>
        /// <param name="filePath">目标文件的完整路径。</param>
        /// <param name="data">要保存的对象实例。</param>
        /// <exception cref="Exception">当保存过程中发生任何错误时抛出。</exception>
        public static async Task SaveAsync<T>(string filePath, T data)
        {
            try
            {
                // 1. 确保文件所在的目录存在，如果不存在则创建
                var directoryPath = Path.GetDirectoryName(filePath);
                if (!string.IsNullOrEmpty(directoryPath) && !Directory.Exists(directoryPath))
                {
                    Directory.CreateDirectory(directoryPath);
                }

                // 2. 使用 JsonHelper 将对象序列化为 JSON 字符串
                string json = JsonHelper.Serialize(data);

                // 3. 使用 StreamWriter 异步将 JSON 字符串写入文件
                //    - `false` 表示覆盖现有文件。
                //    - `Encoding.UTF8` 确保文件编码正确，特别是处理中文字符时。
                using (var writer = new StreamWriter(filePath, false, Encoding.UTF8))
                {
                    await writer.WriteAsync(json);
                }
            }
            catch (Exception ex)
            {
                // 记录错误到调试输出
                System.Diagnostics.Debug.WriteLine($"保存文件失败 [{filePath}]: {ex.Message}");
                // 重新抛出异常，因为保存失败通常是一个需要上层处理的严重问题（例如，提示用户）
                throw;
            }
        }

        #endregion

        #region --- 加载方法 ---

        /// <summary>
        /// 从文件异步加载并反序列化为指定类型的对象。
        /// </summary>
        /// <typeparam name="T">目标对象的类型。必须是引用类型且具有公共无参数构造函数。</typeparam>
        /// <param name="filePath">源文件的完整路径。</param>
        /// <returns>
        /// 成功时返回反序列化后的对象。
        /// 如果文件不存在、内容为空、格式错误或发生任何异常，将返回一个新创建的默认对象实例。
        /// </returns>
        public static async Task<T> LoadAsync<T>(string filePath) where T : class, new()
        {
            // 1. 如果文件不存在，直接返回一个新的默认对象
            if (!File.Exists(filePath))
            {
                return new T();
            }

            try
            {
                // 2. 使用 StreamReader 异步读取文件全部内容
                using (var reader = new StreamReader(filePath, Encoding.UTF8))
                {
                    string json = await reader.ReadToEndAsync();

                    // 3. 如果文件内容为空或只包含空白字符，返回一个新的默认对象
                    if (string.IsNullOrWhiteSpace(json))
                    {
                        return new T();
                    }

                    // 4. 使用 JsonHelper 尝试反序列化 JSON 字符串
                    var result = JsonHelper.Deserialize<T>(json);

                    // 5. 如果反序列化结果为 null (例如，JSON 内容为 "null" 或格式不匹配)，
                    //    则返回一个新的默认对象作为兜底。
                    return result ?? new T();
                }
            }
            catch (Exception ex)
            {
                // 记录错误到调试输出
                System.Diagnostics.Debug.WriteLine($"读取文件失败 [{filePath}]: {ex.Message}");
                // 发生任何异常（如文件被占用、权限问题等），都返回一个新的默认对象，
                // 以确保程序能够继续运行而不会崩溃。
                return new T();
            }
        }

        #endregion
    }
}