//
//  EmailLogService.swift
//  oAI
//
//  Service for managing email handler activity logs
//
// SPDX-License-Identifier: AGPL-3.0-or-later
// Copyright (C) 2026 Rune Olsen
//
// This file is part of oAI.
//
// oAI is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// oAI is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
// Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with oAI. If not, see <https://www.gnu.org/licenses/>.


import Foundation
import os

@Observable
final class EmailLogService {
    static let shared = EmailLogService()

    private let db = DatabaseService.shared
    private let log = Logger(subsystem: "com.oai.oAI", category: "email-log")

    private init() {}

    // MARK: - Log Operations

    /// Save a successful email processing log
    func logSuccess(
        sender: String,
        subject: String,
        emailContent: String,
        aiResponse: String,
        tokens: Int?,
        cost: Double?,
        responseTime: TimeInterval?,
        modelId: String?
    ) {
        let entry = EmailLog(
            sender: sender,
            subject: subject,
            emailContent: emailContent,
            aiResponse: aiResponse,
            status: .success,
            tokens: tokens,
            cost: cost,
            responseTime: responseTime,
            modelId: modelId
        )

        db.saveEmailLog(entry)
        log.info("Email log saved: \(sender) - \(subject) [SUCCESS]")
    }

    /// Save a failed email processing log
    func logError(
        sender: String,
        subject: String,
        emailContent: String,
        errorMessage: String,
        modelId: String?
    ) {
        let entry = EmailLog(
            sender: sender,
            subject: subject,
            emailContent: emailContent,
            aiResponse: nil,
            status: .error,
            errorMessage: errorMessage,
            modelId: modelId
        )

        db.saveEmailLog(entry)
        log.error("Email log saved: \(sender) - \(subject) [ERROR: \(errorMessage)]")
    }

    /// Load recent email logs (default: 100 most recent)
    func loadLogs(limit: Int = 100) -> [EmailLog] {
        do {
            return try db.loadEmailLogs(limit: limit)
        } catch {
            log.error("Failed to load email logs: \(error.localizedDescription)")
            return []
        }
    }

    /// Delete a specific log entry
    func deleteLog(id: UUID) {
        db.deleteEmailLog(id: id)
        log.info("Email log deleted: \(id.uuidString)")
    }

    /// Clear all email logs
    func clearAllLogs() {
        db.clearEmailLogs()
        log.info("All email logs cleared")
    }

    /// Get total count of email logs
    func getLogCount() -> Int {
        do {
            return try db.getEmailLogCount()
        } catch {
            log.error("Failed to get email log count: \(error.localizedDescription)")
            return 0
        }
    }

    // MARK: - Statistics

    /// Get email processing statistics
    func getStatistics() -> EmailStatistics {
        let logs = loadLogs(limit: 1000) // Last 1000 for stats

        let total = logs.count
        let successful = logs.filter { $0.status == .success }.count
        let errors = logs.filter { $0.status == .error }.count

        let totalTokens = logs.compactMap { $0.tokens }.reduce(0, +)
        let totalCost = logs.compactMap { $0.cost }.reduce(0.0, +)

        let avgResponseTime: TimeInterval?
        let responseTimes = logs.compactMap { $0.responseTime }
        if !responseTimes.isEmpty {
            avgResponseTime = responseTimes.reduce(0, +) / Double(responseTimes.count)
        } else {
            avgResponseTime = nil
        }

        return EmailStatistics(
            total: total,
            successful: successful,
            errors: errors,
            totalTokens: totalTokens,
            totalCost: totalCost,
            averageResponseTime: avgResponseTime
        )
    }
}

// MARK: - Statistics Model

struct EmailStatistics {
    let total: Int
    let successful: Int
    let errors: Int
    let totalTokens: Int
    let totalCost: Double
    let averageResponseTime: TimeInterval?

    var successRate: Double {
        guard total > 0 else { return 0.0 }
        return Double(successful) / Double(total)
    }

    var errorRate: Double {
        guard total > 0 else { return 0.0 }
        return Double(errors) / Double(total)
    }
}
