package model

import (
	"fmt"
	"time"
)

// Position represents a calculated position for a specific stock in a portfolio
type Position struct {
	Stock            string    `json:"stock"`              // Stock symbol/ISIN
	Shares           float64   `json:"shares"`             // Total shares held (can be negative if oversold)
	AverageCostPrice float64   `json:"average_cost_price"` // Average cost per share in portfolio base currency
	TotalCostBasis   float64   `json:"total_cost_basis"`   // Total amount invested in portfolio base currency
	CurrentPrice     float64   `json:"current_price"`      // Current market price per share in portfolio base currency
	CurrentValue     float64   `json:"current_value"`      // Current total value (shares * current_price)
	UnrealizedPL     float64   `json:"unrealized_pl"`      // Unrealized profit/loss (current_value - total_cost_basis)
	UnrealizedPLPct  float64   `json:"unrealized_pl_pct"`  // Unrealized profit/loss percentage
	Currency         string    `json:"currency"`           // Stock's native currency
	BaseCurrency     string    `json:"base_currency"`      // Portfolio's base currency
	LastUpdated      time.Time `json:"last_updated"`       // When position was last calculated

	// Dividend information
	TotalDividends float64 `json:"total_dividends"` // Total dividends received in base currency

	// Transaction summary
	TotalBought float64 `json:"total_bought"` // Total shares bought
	TotalSold   float64 `json:"total_sold"`   // Total shares sold
	RealizedPL  float64 `json:"realized_pl"`  // Realized profit/loss from sales
}

// PositionSummary represents aggregated portfolio position data
type PositionSummary struct {
	TotalValue        float64   `json:"total_value"`         // Total portfolio value
	TotalCostBasis    float64   `json:"total_cost_basis"`    // Total amount invested
	TotalUnrealizedPL float64   `json:"total_unrealized_pl"` // Total unrealized profit/loss
	TotalRealizedPL   float64   `json:"total_realized_pl"`   // Total realized profit/loss
	TotalDividends    float64   `json:"total_dividends"`     // Total dividends received
	TotalReturn       float64   `json:"total_return"`        // Total return (realized + unrealized + dividends)
	TotalReturnPct    float64   `json:"total_return_pct"`    // Total return percentage
	Currency          string    `json:"currency"`            // Portfolio base currency
	LastUpdated       time.Time `json:"last_updated"`        // When summary was calculated
}

// IsOpen returns true if the position has shares (positive or negative)
func (p *Position) IsOpen() bool {
	return p.Shares != 0
}

// IsLong returns true if the position has positive shares
func (p *Position) IsLong() bool {
	return p.Shares > 0
}

// IsShort returns true if the position has negative shares
func (p *Position) IsShort() bool {
	return p.Shares < 0
}

// GetDisplayValue returns the absolute value for display purposes
func (p *Position) GetDisplayValue() float64 {
	if p.CurrentValue < 0 {
		return -p.CurrentValue
	}
	return p.CurrentValue
}

// GetUnrealizedPLColor returns CSS class for profit/loss color
func (p *Position) GetUnrealizedPLColor() string {
	if p.UnrealizedPL > 0 {
		return "text-green"
	} else if p.UnrealizedPL < 0 {
		return "text-red"
	}
	return "text-muted"
}

// GetUnrealizedPLIcon returns icon for profit/loss
func (p *Position) GetUnrealizedPLIcon() string {
	if p.UnrealizedPL > 0 {
		return "trending-up"
	} else if p.UnrealizedPL < 0 {
		return "trending-down"
	}
	return "minus"
}

// FormatCurrency formats a value with currency symbol
func (p *Position) FormatCurrency(value float64) string {
	switch p.BaseCurrency {
	case "EUR":
		return fmt.Sprintf("€%.2f", value)
	case "USD":
		return fmt.Sprintf("$%.2f", value)
	case "GBP":
		return fmt.Sprintf("£%.2f", value)
	case "CHF":
		return fmt.Sprintf("%.2f CHF", value)
	default:
		return fmt.Sprintf("%.2f %s", value, p.BaseCurrency)
	}
}

// FormatShares formats share count with appropriate decimal places
func (p *Position) FormatShares() string {
	if p.Shares == float64(int(p.Shares)) {
		return fmt.Sprintf("%.0f", p.Shares)
	}
	return fmt.Sprintf("%.4f", p.Shares)
}

// FormatPercentage formats percentage with sign and color
func (p *Position) FormatPercentage() string {
	if p.UnrealizedPLPct > 0 {
		return fmt.Sprintf("+%.2f%%", p.UnrealizedPLPct)
	}
	return fmt.Sprintf("%.2f%%", p.UnrealizedPLPct)
}
