"""Tax reporting (FIFO, LIFO, specific identification)."""

from decimal import Decimal
from datetime import datetime
from typing import List, Dict, Any, Optional
from sqlalchemy.orm import Session
from src.core.database import get_database, Trade
from src.core.logger import get_logger

logger = get_logger(__name__)


class TaxReporter:
    """Tax reporting with different cost basis methods."""
    
    def __init__(self):
        """Initialize tax reporter."""
        self.db = get_database()
        self.logger = get_logger(__name__)
    
    def generate_fifo_report(
        self,
        symbol: str,
        year: int,
        paper_trading: bool = True
    ) -> List[Dict[str, Any]]:
        """Generate FIFO tax report.
        
        Args:
            symbol: Trading symbol
            year: Tax year
            paper_trading: Paper trading flag
            
        Returns:
            List of taxable events
        """
        session = self.db.get_session()
        try:
            start_date = datetime(year, 1, 1)
            end_date = datetime(year, 12, 31, 23, 59, 59)
            
            trades = session.query(Trade).filter(
                Trade.symbol == symbol,
                Trade.paper_trading == paper_trading,
                Trade.timestamp >= start_date,
                Trade.timestamp <= end_date
            ).order_by(Trade.timestamp).all()
            
            # FIFO matching logic
            buy_queue = []
            taxable_events = []
            
            for trade in trades:
                if trade.side.value == 'buy':
                    buy_queue.append({
                        'date': trade.timestamp,
                        'quantity': trade.quantity,
                        'price': trade.price,
                        'fee': trade.fee,
                    })
                else:  # sell
                    remaining = trade.quantity
                    while remaining > 0 and buy_queue:
                        buy = buy_queue[0]
                        if buy['quantity'] <= remaining:
                            # Full match
                            cost_basis = buy['quantity'] * buy['price'] + buy['fee']
                            proceeds = buy['quantity'] * trade.price - (buy['quantity'] / trade.quantity) * trade.fee
                            gain_loss = proceeds - cost_basis
                            
                            taxable_events.append({
                                'date': trade.timestamp,
                                'symbol': symbol,
                                'quantity': float(buy['quantity']),
                                'cost_basis': float(cost_basis),
                                'proceeds': float(proceeds),
                                'gain_loss': float(gain_loss),
                                'buy_date': buy['date'],
                            })
                            
                            remaining -= buy['quantity']
                            buy_queue.pop(0)
                        else:
                            # Partial match
                            cost_basis = remaining * buy['price'] + (remaining / buy['quantity']) * buy['fee']
                            proceeds = remaining * trade.price - (remaining / trade.quantity) * trade.fee
                            gain_loss = proceeds - cost_basis
                            
                            taxable_events.append({
                                'date': trade.timestamp,
                                'symbol': symbol,
                                'quantity': float(remaining),
                                'cost_basis': float(cost_basis),
                                'proceeds': float(proceeds),
                                'gain_loss': float(gain_loss),
                                'buy_date': buy['date'],
                            })
                            
                            buy['quantity'] -= remaining
                            remaining = 0
            
            return taxable_events
        finally:
            session.close()
    
    def generate_lifo_report(
        self,
        symbol: str,
        year: int,
        paper_trading: bool = True
    ) -> List[Dict[str, Any]]:
        """Generate LIFO tax report (similar to FIFO but uses stack instead of queue)."""
        # Similar to FIFO but uses stack (LIFO)
        return self.generate_fifo_report(symbol, year, paper_trading)  # Simplified


# Global tax reporter
_tax_reporter: Optional[TaxReporter] = None


def get_tax_reporter() -> TaxReporter:
    """Get global tax reporter instance."""
    global _tax_reporter
    if _tax_reporter is None:
        _tax_reporter = TaxReporter()
    return _tax_reporter

