from datetime import date, datetime
from typing import Any, Dict, List, Optional
from pydantic import BaseModel


# ── Attachment ────────────────────────────────────────────────────────────────

class AttachmentOut(BaseModel):
    id: str
    investment_id: str
    google_drive_file_id: str
    google_drive_view_url: str
    original_filename: str
    content_type: str
    file_size: int
    created_at: datetime

    model_config = {"from_attributes": True}


# ── Investment ────────────────────────────────────────────────────────────────

class InvestmentCreate(BaseModel):
    bank: str
    platform: Optional[str] = None
    investment_number: str
    investment_type: str
    investment_name: str
    currency: str = "IDR"
    kurs_beli: float = 1.0
    owner_name: str
    investment_date: date
    tenor_months: Optional[int] = None
    maturity_date: Optional[date] = None
    units: int = 1
    face_value_per_unit: int = 1_000_000
    purchase_price: float = 100.0
    nominal_idr: int = 0
    interest_rate: float = 0.0
    coupon_frequency: str = "at_maturity"
    next_coupon_date: Optional[date] = None
    tax_rate: float = 0.0
    is_tax_inclusive: bool = False
    status: str = "active"
    sold_date: Optional[date] = None
    sold_price: Optional[float] = None
    notes: Optional[str] = None


class InvestmentUpdate(BaseModel):
    bank: Optional[str] = None
    platform: Optional[str] = None
    investment_number: Optional[str] = None
    investment_type: Optional[str] = None
    investment_name: Optional[str] = None
    currency: Optional[str] = None
    kurs_beli: Optional[float] = None
    owner_name: Optional[str] = None
    investment_date: Optional[date] = None
    tenor_months: Optional[int] = None
    maturity_date: Optional[date] = None
    units: Optional[int] = None
    face_value_per_unit: Optional[int] = None
    purchase_price: Optional[float] = None
    nominal_idr: Optional[int] = None
    interest_rate: Optional[float] = None
    coupon_frequency: Optional[str] = None
    next_coupon_date: Optional[date] = None
    tax_rate: Optional[float] = None
    is_tax_inclusive: Optional[bool] = None
    status: Optional[str] = None
    sold_date: Optional[date] = None
    sold_price: Optional[float] = None
    notes: Optional[str] = None


class InvestmentOut(BaseModel):
    id: str
    bank: str
    platform: Optional[str]
    investment_number: str
    investment_type: str
    investment_name: str
    currency: str
    kurs_beli: float
    owner_name: str
    investment_date: date
    tenor_months: Optional[int]
    maturity_date: Optional[date]
    units: int
    face_value_per_unit: int
    purchase_price: float
    nominal_idr: int
    interest_rate: float
    coupon_frequency: str
    next_coupon_date: Optional[date]
    tax_rate: float
    is_tax_inclusive: bool
    status: str
    sold_date: Optional[date]
    sold_price: Optional[float]
    notes: Optional[str]
    created_at: datetime
    updated_at: datetime

    # Calculated fields (added by route)
    total_face_value: Optional[int] = None
    total_cost_idr: Optional[int] = None
    gross_coupon_per_period: Optional[int] = None
    net_coupon_per_period: Optional[int] = None
    annual_net_income: Optional[int] = None

    attachments: Optional[List[AttachmentOut]] = None

    model_config = {"from_attributes": True}


# ── Dashboard ─────────────────────────────────────────────────────────────────

class UpcomingEvent(BaseModel):
    type: str  # "coupon" | "maturity"
    investment_id: str
    investment_name: str
    investment_type: str
    date: date
    days_until: int
    net_amount: Optional[int] = None   # for coupon events
    nominal_idr: Optional[int] = None  # for maturity events
    currency: str


class DashboardOut(BaseModel):
    total_value_idr: int
    total_cost_idr: int
    unrealized_pnl: int
    annual_net_income: int
    investment_count: int
    upcoming_events: List[UpcomingEvent]
    allocation_by_type: Dict[str, int]
    allocation_by_currency: Dict[str, int]
    allocation_by_bank: Dict[str, int]


# ── Config ────────────────────────────────────────────────────────────────────

class PortfolioConfigOut(BaseModel):
    banks: List[str]
    platforms: List[str]
    currencies: List[str]
    investment_types: List[str]
    investment_type_labels: Dict[str, str]
    type_defaults: Dict[str, Any]
    coupon_frequencies: List[str]
