import Foundation

struct InvestmentMetrics {
    // Basic Metrics
    let totalValue: Decimal
    let totalContributions: Decimal
    let absoluteReturn: Decimal
    let percentageReturn: Decimal

    // Advanced Metrics
    let cagr: Double // Compound Annual Growth Rate
    let twr: Double // Time-Weighted Return
    let volatility: Double // Standard deviation annualized
    let maxDrawdown: Double // Maximum peak-to-trough decline
    let sharpeRatio: Double // Risk-adjusted return
    let bestMonth: MonthlyReturn?
    let worstMonth: MonthlyReturn?
    let winRate: Double // Percentage of positive months
    let averageMonthlyReturn: Double

    // Time period
    let startDate: Date?
    let endDate: Date?
    let totalMonths: Int

    struct MonthlyReturn: Identifiable {
        let id = UUID()
        let date: Date
        let returnPercentage: Double

        var formattedDate: String {
            let formatter = DateFormatter()
            formatter.dateFormat = "MMM yyyy"
            return formatter.string(from: date)
        }

        var formattedReturn: String {
            String(format: "%.1f%%", returnPercentage)
        }
    }
}

// MARK: - Formatting Helpers

extension InvestmentMetrics {
    var formattedTotalValue: String {
        formatCurrency(totalValue)
    }

    var formattedAbsoluteReturn: String {
        let prefix = absoluteReturn >= 0 ? "+" : ""
        return prefix + formatCurrency(absoluteReturn)
    }

    var formattedPercentageReturn: String {
        let prefix = percentageReturn >= 0 ? "+" : ""
        return String(format: "\(prefix)%.2f%%", NSDecimalNumber(decimal: percentageReturn).doubleValue)
    }

    var formattedCAGR: String {
        String(format: "%.2f%%", cagr)
    }

    var formattedTWR: String {
        String(format: "%.2f%%", twr)
    }

    var formattedVolatility: String {
        String(format: "%.2f%%", volatility)
    }

    var formattedMaxDrawdown: String {
        String(format: "%.2f%%", maxDrawdown)
    }

    var formattedSharpeRatio: String {
        String(format: "%.2f", sharpeRatio)
    }

    var formattedWinRate: String {
        String(format: "%.0f%%", winRate)
    }

    var formattedAverageMonthlyReturn: String {
        let prefix = averageMonthlyReturn >= 0 ? "+" : ""
        return String(format: "\(prefix)%.2f%%", averageMonthlyReturn)
    }

    private func formatCurrency(_ value: Decimal) -> String {
        CurrencyFormatter.format(value, style: .currency, maximumFractionDigits: 2)
    }
}

// MARK: - Empty State

extension InvestmentMetrics {
    static var empty: InvestmentMetrics {
        InvestmentMetrics(
            totalValue: 0,
            totalContributions: 0,
            absoluteReturn: 0,
            percentageReturn: 0,
            cagr: 0,
            twr: 0,
            volatility: 0,
            maxDrawdown: 0,
            sharpeRatio: 0,
            bestMonth: nil,
            worstMonth: nil,
            winRate: 0,
            averageMonthlyReturn: 0,
            startDate: nil,
            endDate: nil,
            totalMonths: 0
        )
    }
}

// MARK: - Category Metrics

struct CategoryMetrics: Identifiable {
    let id: UUID
    let categoryName: String
    let colorHex: String
    let icon: String
    let totalValue: Decimal
    let percentageOfPortfolio: Double
    let metrics: InvestmentMetrics

    var formattedTotalValue: String {
        CurrencyFormatter.format(totalValue, style: .currency, maximumFractionDigits: 0)
    }

    var formattedPercentage: String {
        String(format: "%.1f%%", percentageOfPortfolio)
    }
}

// MARK: - Portfolio Summary

struct PortfolioSummary {
    let totalValue: Decimal
    let totalContributions: Decimal
    let dayChange: Decimal
    let dayChangePercentage: Double
    let weekChange: Decimal
    let weekChangePercentage: Double
    let monthChange: Decimal
    let monthChangePercentage: Double
    let yearChange: Decimal
    let yearChangePercentage: Double
    let allTimeReturn: Decimal
    let allTimeReturnPercentage: Double
    let sourceCount: Int
    let lastUpdated: Date?

    var formattedTotalValue: String {
        CurrencyFormatter.format(totalValue, style: .currency, maximumFractionDigits: 0)
    }

    var formattedDayChange: String {
        formatChange(dayChange, dayChangePercentage)
    }

    var formattedMonthChange: String {
        formatChange(monthChange, monthChangePercentage)
    }

    var formattedYearChange: String {
        formatChange(yearChange, yearChangePercentage)
    }

    var formattedAllTimeReturn: String {
        formatChange(allTimeReturn, allTimeReturnPercentage)
    }

    private func formatChange(_ absolute: Decimal, _ percentage: Double) -> String {
        let prefix = absolute >= 0 ? "+" : ""
        let absString = CurrencyFormatter.format(absolute, style: .currency, maximumFractionDigits: 0)
        let pctString = String(format: "%.2f%%", percentage)

        return "\(prefix)\(absString) (\(prefix)\(pctString))"
    }

    static var empty: PortfolioSummary {
        PortfolioSummary(
            totalValue: 0,
            totalContributions: 0,
            dayChange: 0,
            dayChangePercentage: 0,
            weekChange: 0,
            weekChangePercentage: 0,
            monthChange: 0,
            monthChangePercentage: 0,
            yearChange: 0,
            yearChangePercentage: 0,
            allTimeReturn: 0,
            allTimeReturnPercentage: 0,
            sourceCount: 0,
            lastUpdated: nil
        )
    }
}

// MARK: - Portfolio Forecast

struct PortfolioForecast {
    let currentValue: Decimal
    let forecastValue: Decimal
    let forecastDate: Date
    let confidenceLower: Decimal
    let confidenceUpper: Decimal
    let monthlyGrowthRate: Decimal
    let annualizedGrowthRate: Decimal

    var formattedForecastValue: String {
        CurrencyFormatter.format(forecastValue, style: .currency, maximumFractionDigits: 0)
    }

    var formattedCurrentValue: String {
        CurrencyFormatter.format(currentValue, style: .currency, maximumFractionDigits: 0)
    }

    var formattedConfidenceRange: String {
        let lower = CurrencyFormatter.format(confidenceLower, style: .currency, maximumFractionDigits: 0)
        let upper = CurrencyFormatter.format(confidenceUpper, style: .currency, maximumFractionDigits: 0)
        return "\(lower) – \(upper)"
    }

    var formattedForecastDate: String {
        forecastDate.monthYearString
    }

    var formattedGrowthPercentage: String {
        guard currentValue > 0 else { return "+0%" }
        let growthPct = ((forecastValue - currentValue) / currentValue) * 100
        let prefix = growthPct >= 0 ? "+" : ""
        return String(format: "\(prefix)%.1f%%", NSDecimalNumber(decimal: growthPct).doubleValue)
    }

    var formattedAnnualizedGrowthRate: String {
        let prefix = annualizedGrowthRate >= 0 ? "+" : ""
        return String(format: "\(prefix)%.1f%%", NSDecimalNumber(decimal: annualizedGrowthRate * 100).doubleValue)
    }

    var isPositiveGrowth: Bool {
        forecastValue >= currentValue
    }
}
