using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using XplorePlane.Models;

namespace XplorePlane.Services
{
    public class PipelinePersistenceService : IPipelinePersistenceService
    {
        private readonly IImageProcessingService _imageProcessingService;
        private readonly string _baseDirectory;

        private static readonly JsonSerializerOptions JsonOptions = new()
        {
            WriteIndented = true,
            DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
            Converters = { new JsonStringEnumConverter() }
        };

        public PipelinePersistenceService(IImageProcessingService imageProcessingService, string baseDirectory = null)
        {
            _imageProcessingService = imageProcessingService ?? throw new ArgumentNullException(nameof(imageProcessingService));
            _baseDirectory = baseDirectory ?? Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
                "XplorePlane", "Pipelines");
        }

        public async Task SaveAsync(PipelineModel pipeline, string filePath)
        {
            if (pipeline == null) throw new ArgumentNullException(nameof(pipeline));
            ValidatePath(filePath);

            pipeline.UpdatedAt = DateTime.UtcNow;
            var json = JsonSerializer.Serialize(pipeline, JsonOptions);
            await File.WriteAllTextAsync(filePath, json);
        }

        public async Task<PipelineModel> LoadAsync(string filePath)
        {
            ValidatePath(filePath);

            if (!File.Exists(filePath))
                throw new FileNotFoundException("流水线文件不存在", filePath);

            var json = await File.ReadAllTextAsync(filePath);
            var model = JsonSerializer.Deserialize<PipelineModel>(json, JsonOptions)
                ?? throw new InvalidDataException("流水线文件格式无效");

            // 白名单验证：过滤未注册的算子键
            var available = _imageProcessingService.GetAvailableProcessors().ToHashSet(StringComparer.OrdinalIgnoreCase);
            model.Nodes = model.Nodes
                .Where(n => available.Contains(n.OperatorKey))
                .OrderBy(n => n.Order)
                .ToList();

            // 重新编号确保 Order 连续
            for (int i = 0; i < model.Nodes.Count; i++)
                model.Nodes[i].Order = i;

            return model;
        }

        public async Task<IReadOnlyList<PipelineModel>> LoadAllAsync(string directory)
        {
            if (string.IsNullOrWhiteSpace(directory))
                directory = _baseDirectory;

            ValidateDirectory(directory);

            if (!Directory.Exists(directory))
                return Array.Empty<PipelineModel>();

            var files = Directory.GetFiles(directory, "*.pipeline.json");
            var results = new List<PipelineModel>();

            foreach (var file in files)
            {
                try
                {
                    var model = await LoadAsync(file);
                    results.Add(model);
                }
                catch
                {
                    // 跳过无效文件
                }
            }

            return results;
        }

        private void ValidatePath(string filePath)
        {
            if (string.IsNullOrWhiteSpace(filePath))
                throw new ArgumentException("文件路径不能为空", nameof(filePath));

            if (filePath.Contains(".."))
                throw new UnauthorizedAccessException($"不允许路径遍历：{filePath}");
        }

        private void ValidateDirectory(string directory)
        {
            if (directory.Contains(".."))
                throw new UnauthorizedAccessException($"不允许路径遍历：{directory}");
        }
    }
}
