using System.Security.Cryptography;
using System.Text;
using Microsoft.JSInterop;
using System.Text.Json;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

namespace Front.Program.Services;

public class SecureService
{
    private readonly ILogger<SecureService> _logger;
    private readonly IJSRuntime _jsRuntime;
    private readonly IWebAssemblyHostEnvironment _environment;
    private string? _key;
    private string? _iv;
    private Task? _initializationTask;

    public SecureService(
        ILogger<SecureService> logger, 
        IJSRuntime jsRuntime,
        IWebAssemblyHostEnvironment environment)
    {
        _logger = logger;
        _jsRuntime = jsRuntime;
        _environment = environment;
        _initializationTask = InitializeAsync();
    }

    private async Task InitializeAsync()
    {
        try
        {
            var configFile = $"appsettings.{_environment.Environment}.json";
            _logger.LogInformation($"설정 파일 로드: {configFile}");
            
            var config = await _jsRuntime.InvokeAsync<JsonElement>("loadConfig", configFile);
            if (config.ValueKind == JsonValueKind.Null)
            {
                throw new InvalidOperationException($"설정 파일을 로드할 수 없습니다: {configFile}");
            }
            
            var security = config.GetProperty("Security");
            _key = security.GetProperty("EncryptionKey").GetString() 
                ?? throw new ArgumentNullException("Security:EncryptionKey");
            _iv = security.GetProperty("EncryptionIV").GetString() 
                ?? throw new ArgumentNullException("Security:EncryptionIV");
        }
        catch (Exception ex)
        {
            _logger.LogError($"설정 로드 중 오류 발생: {ex.Message}");
            throw;
        }
    }

    private async Task EnsureInitializedAsync()
    {
        if (_initializationTask != null)
        {
            await _initializationTask;
            _initializationTask = null;
        }
    }

    private byte[] GetKeyBytes(string key)
    {
        using (var sha256 = SHA256.Create())
        {
            return sha256.ComputeHash(Encoding.UTF8.GetBytes(key));
        }
    }

    private byte[] GetIVBytes(string iv)
    {
        using (var sha256 = SHA256.Create())
        {
            var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(iv));
            return hash.Take(16).ToArray(); // IV는 16바이트만 필요
        }
    }

    public async Task<string> EncryptAsync(string plainText)
    {
        await EnsureInitializedAsync();
        
        if (_key == null || _iv == null)
            throw new InvalidOperationException("암호화 키가 초기화되지 않았습니다.");

        try
        {
            return await _jsRuntime.InvokeAsync<string>("encryptText", plainText, _key, _iv);
        }
        catch (Exception ex)
        {
            _logger.LogError($"암호화 중 오류 발생: {ex.Message}");
            throw;
        }
    }

    public async Task<string> DecryptAsync(string cipherText)
    {
        await EnsureInitializedAsync();
        
        if (_key == null || _iv == null)
            throw new InvalidOperationException("암호화 키가 초기화되지 않았습니다.");

        try
        {
            return await _jsRuntime.InvokeAsync<string>("decryptText", cipherText, _key, _iv);
        }
        catch (Exception ex)
        {
            _logger.LogError($"복호화 중 오류 발생: {ex.Message}");
            throw;
        }
    }

    // 동기 메서드는 비동기 메서드를 호출하도록 수정
    public string Encrypt(string plainText) => EncryptAsync(plainText).GetAwaiter().GetResult();
    public string Decrypt(string cipherText) => DecryptAsync(cipherText).GetAwaiter().GetResult();
} 