using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using System.Security.Cryptography;
using System.Text;

namespace JobTrackerApi.Services
{
    public sealed class AppPaths
    {
        public string DataRoot { get; }
        public string AttachmentsRoot { get; }
        public string CvArtifactsRoot { get; }
        public string CvExportsRoot { get; }
        public string CvBenchmarksRoot { get; }
        public string AccountDeletionTombstonesRoot { get; }

        public AppPaths(IConfiguration cfg, IHostEnvironment env)
        {
            var dataRoot = (cfg["Data:Root"] ?? "").Trim();
            if (string.IsNullOrWhiteSpace(dataRoot)) dataRoot = env.ContentRootPath;
            if (!Path.IsPathRooted(dataRoot)) dataRoot = Path.Combine(env.ContentRootPath, dataRoot);

            Directory.CreateDirectory(dataRoot);
            DataRoot = dataRoot;

            var attachmentsRoot = (cfg["Data:AttachmentsRoot"] ?? "").Trim();
            if (string.IsNullOrWhiteSpace(attachmentsRoot)) attachmentsRoot = Path.Combine(DataRoot, "Attachments");
            if (!Path.IsPathRooted(attachmentsRoot)) attachmentsRoot = Path.Combine(env.ContentRootPath, attachmentsRoot);

            Directory.CreateDirectory(attachmentsRoot);
            AttachmentsRoot = attachmentsRoot;

            var cvArtifactsRoot = (cfg["Data:CvArtifactsRoot"] ?? "").Trim();
            if (string.IsNullOrWhiteSpace(cvArtifactsRoot)) cvArtifactsRoot = Path.Combine(DataRoot, "CvArtifacts");
            if (!Path.IsPathRooted(cvArtifactsRoot)) cvArtifactsRoot = Path.Combine(env.ContentRootPath, cvArtifactsRoot);

            Directory.CreateDirectory(cvArtifactsRoot);
            CvArtifactsRoot = cvArtifactsRoot;

            var cvExportsRoot = (cfg["Data:CvExportsRoot"] ?? "").Trim();
            if (string.IsNullOrWhiteSpace(cvExportsRoot)) cvExportsRoot = Path.Combine(DataRoot, "CvExports");
            if (!Path.IsPathRooted(cvExportsRoot)) cvExportsRoot = Path.Combine(env.ContentRootPath, cvExportsRoot);

            Directory.CreateDirectory(cvExportsRoot);
            CvExportsRoot = cvExportsRoot;

            var cvBenchmarksRoot = (cfg["Data:CvBenchmarksRoot"] ?? "").Trim();
            if (string.IsNullOrWhiteSpace(cvBenchmarksRoot)) cvBenchmarksRoot = Path.Combine(DataRoot, "CvBenchmarks");
            if (!Path.IsPathRooted(cvBenchmarksRoot)) cvBenchmarksRoot = Path.Combine(env.ContentRootPath, cvBenchmarksRoot);

            Directory.CreateDirectory(cvBenchmarksRoot);
            CvBenchmarksRoot = cvBenchmarksRoot;

            var tombstonesRoot = (cfg["AccountLifecycle:TombstonesRoot"] ?? "").Trim();
            if (string.IsNullOrWhiteSpace(tombstonesRoot)) tombstonesRoot = Path.Combine(DataRoot, "DeletionTombstones");
            if (!Path.IsPathRooted(tombstonesRoot)) tombstonesRoot = Path.Combine(env.ContentRootPath, tombstonesRoot);
            Directory.CreateDirectory(tombstonesRoot);
            AccountDeletionTombstonesRoot = tombstonesRoot;
        }

        public string GetDbPath(string fileName = "jobtracker.db") => Path.Combine(DataRoot, fileName);

        public string GetExportsRoot(string? configuredFolder)
        {
            var folder = (configuredFolder ?? "").Trim();
            if (string.IsNullOrWhiteSpace(folder)) return Path.Combine(DataRoot, "exports");
            return Path.IsPathRooted(folder) ? folder : Path.Combine(DataRoot, folder);
        }

        public static string GetOwnerStorageKey(string ownerUserId)
        {
            ArgumentException.ThrowIfNullOrWhiteSpace(ownerUserId);
            return Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(ownerUserId))).ToLowerInvariant();
        }

        public string GetOwnerCvExportsRoot(string ownerUserId) =>
            Path.Combine(CvExportsRoot, GetOwnerStorageKey(ownerUserId));

        public string GetOwnerDailyExportsRoot(string? configuredFolder, string ownerUserId) =>
            Path.Combine(GetExportsRoot(configuredFolder), GetOwnerStorageKey(ownerUserId));

        public string GetOwnerAccountExportsRoot(string ownerUserId) =>
            Path.Combine(DataRoot, "AccountExports", GetOwnerStorageKey(ownerUserId));
    }
}

