using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
using TaxBaik.Application.Services;

namespace TaxBaik.Web.Services;

public class TelegramInquiryNotificationService : IInquiryNotificationService
{
    private readonly IHttpClientFactory _httpClientFactory;
    private readonly IConfiguration _configuration;
    private readonly ILogger<TelegramInquiryNotificationService> _logger;
    private readonly string _baseUrl;

    public TelegramInquiryNotificationService(IHttpClientFactory httpClientFactory, IConfiguration configuration, ILogger<TelegramInquiryNotificationService> logger)
    {
        _httpClientFactory = httpClientFactory;
        _configuration = configuration;
        _logger = logger;
        _baseUrl = (_configuration["App:PublicBaseUrl"] ?? "https://www.taxbaik.com").TrimEnd('/');
    }

    public async Task NotifyCreatedAsync(int inquiryId, string name, string phone, string serviceType, string message, string? ipAddress, DateTime createdAtUtc, CancellationToken ct = default)
    {
        _logger.LogInformation("[Telegram] NotifyCreatedAsync 시작: InquiryId={Id}, Name={Name}", inquiryId, name);

        var botToken = _configuration["Telegram:BotToken"];
        
        // 테스트 계정 또는 테스트용 상담 신청인지 감지 (이름에 E2E, Test, Public 등이 포함된 경우)
        var isTestInquiry = name.Contains("E2E", StringComparison.OrdinalIgnoreCase) || 
                            name.Contains("Test", StringComparison.OrdinalIgnoreCase) || 
                            name.Contains("Public", StringComparison.OrdinalIgnoreCase);

        var chatId = isTestInquiry 
            ? _configuration["Telegram:SystemChatId"] 
            : _configuration["Telegram:InquiryChatId"];

        if (string.IsNullOrWhiteSpace(chatId))
            chatId = _configuration["Telegram:ChatId"];

        _logger.LogInformation("[Telegram] 설정 확인: BotToken={Token}, ChatId={ChatId}, IsTestInquiry={IsTest}",
            string.IsNullOrWhiteSpace(botToken) ? "없음" : "있음", chatId, isTestInquiry);

        if (string.IsNullOrWhiteSpace(botToken) || string.IsNullOrWhiteSpace(chatId))
        {
            _logger.LogWarning("텔레그램 새 문의 알림 설정이 누락되었습니다. Telegram:BotToken 또는 Telegram:InquiryChatId/ChatId를 확인하세요.");
            return;
        }

        var adminLink = $"{_baseUrl}/admin/inquiries";
        var summary = message.Length > 180 ? message[..180] + "..." : message;
        var createdAtKst = createdAtUtc.AddHours(9);
        var text = new StringBuilder()
            .AppendLine("🆕 새 문의가 접수되었습니다.")
            .AppendLine()
            .AppendLine($"문의 번호: #{inquiryId}")
            .AppendLine($"제목: {serviceType}")
            .AppendLine($"이름: {name}")
            .AppendLine($"연락처: {phone}")
            .AppendLine($"접수 시각: {createdAtKst:yyyy-MM-dd HH:mm:ss} KST")
            .AppendLine($"IP: {(string.IsNullOrWhiteSpace(ipAddress) ? "-" : ipAddress)}")
            .AppendLine()
            .AppendLine("내용 요약:")
            .AppendLine(summary)
            .AppendLine()
            .AppendLine($"답변 목록 링크: {adminLink}")
            .ToString();

        var client = _httpClientFactory.CreateClient();
        client.Timeout = TimeSpan.FromSeconds(5);
        var url = $"https://api.telegram.org/bot{botToken}/sendMessage";
        var payload = new
        {
            chat_id = chatId,
            text,
            disable_web_page_preview = false
        };

        try
        {
            var response = await client.PostAsJsonAsync(url, payload, ct);
            var responseBody = await response.Content.ReadAsStringAsync(ct);
            if (!response.IsSuccessStatusCode)
            {
                _logger.LogWarning("텔레그램 알림 전송 실패: {StatusCode} {ResponseBody}", response.StatusCode, Truncate(responseBody));
            }
            else
            {
                _logger.LogInformation("텔레그램 새 문의 알림 전송 성공: #{InquiryId}, message_id={MessageId}", inquiryId, TryGetMessageId(responseBody));
            }
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "텔레그램 알림 전송 중 오류 발생");
        }
    }

    public async Task NotifyStatusChangedAsync(int inquiryId, string name, string phone, string serviceType, string previousStatus, string newStatus, string? changedBy = null, CancellationToken ct = default)
    {
        var botToken = _configuration["Telegram:BotToken"];
        
        // 테스트 계정 또는 테스트용 상담 신청인지 감지
        var isTestInquiry = name.Contains("E2E", StringComparison.OrdinalIgnoreCase) || 
                            name.Contains("Test", StringComparison.OrdinalIgnoreCase) || 
                            name.Contains("Public", StringComparison.OrdinalIgnoreCase);

        var chatId = isTestInquiry 
            ? _configuration["Telegram:SystemChatId"] 
            : _configuration["Telegram:InquiryChatId"];

        if (string.IsNullOrWhiteSpace(chatId))
            chatId = _configuration["Telegram:ChatId"];

        if (string.IsNullOrWhiteSpace(botToken) || string.IsNullOrWhiteSpace(chatId))
        {
            _logger.LogWarning("텔레그램 상태 변경 알림 설정이 누락되었습니다. Telegram:BotToken 또는 Telegram:InquiryChatId/ChatId를 확인하세요.");
            return;
        }

        var adminLink = $"{_baseUrl}/admin/inquiries";
        var text = new StringBuilder()
            .AppendLine("✏️ 문의 상태가 변경되었습니다.")
            .AppendLine()
            .AppendLine($"문의 번호: #{inquiryId}")
            .AppendLine($"제목: {serviceType}")
            .AppendLine($"이름: {name}")
            .AppendLine($"연락처: {phone}")
            .AppendLine($"상태: {FormatStatus(previousStatus)} -> {FormatStatus(newStatus)}")
            .AppendLine($"변경자: {(string.IsNullOrWhiteSpace(changedBy) ? "-" : changedBy)}")
            .AppendLine()
            .AppendLine($"답변 목록 링크: {adminLink}")
            .ToString();

        var client = _httpClientFactory.CreateClient();
        client.Timeout = TimeSpan.FromSeconds(5);
        var url = $"https://api.telegram.org/bot{botToken}/sendMessage";
        var payload = new
        {
            chat_id = chatId,
            text,
            disable_web_page_preview = false
        };

        try
        {
            var response = await client.PostAsJsonAsync(url, payload, ct);
            var responseBody = await response.Content.ReadAsStringAsync(ct);
            if (!response.IsSuccessStatusCode)
            {
                _logger.LogWarning("텔레그램 상태 변경 알림 실패: {StatusCode} {ResponseBody}", response.StatusCode, Truncate(responseBody));
            }
            else
            {
                _logger.LogInformation("텔레그램 상태 변경 알림 전송 성공: #{InquiryId}, message_id={MessageId}", inquiryId, TryGetMessageId(responseBody));
            }
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "텔레그램 상태 변경 알림 중 오류 발생");
        }
    }

    private static string FormatStatus(string status) => status switch
    {
        "new" => "신규",
        "contacted" => "연락함",
        "completed" => "완료",
        _ => status
    };

    private static string TryGetMessageId(string responseBody)
    {
        try
        {
            using var document = JsonDocument.Parse(responseBody);
            if (document.RootElement.TryGetProperty("result", out var result)
                && result.TryGetProperty("message_id", out var messageId))
            {
                return messageId.ToString();
            }
        }
        catch (JsonException)
        {
            return "unknown";
        }

        return "unknown";
    }

    private static string Truncate(string value)
        => value.Length <= 500 ? value : value[..500] + "...";
}
