from __future__ import annotations
import uuid
from decimal import Decimal, ROUND_HALF_UP, InvalidOperation
from typing import Any, Dict, List, Optional
from core.config import logger
# TaxProfile ve TaxProfileItem eklendi
from core.db import BaseManager, DataManager, TaxApplication, TaxDefinition, TaxProfile, TaxProfileItem

def _to_decimal(value: Any, default: Decimal = Decimal("0")) -> Decimal:
    if value is None: return default
    if isinstance(value, Decimal): return value
    try:
        val_str = str(value).replace(",", ".")
        return Decimal(val_str)
    except Exception:
        return default

def _money(value: Decimal) -> Decimal:
    return value.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)

class TaxDefinitionManager(BaseManager):
    def __init__(self, data_manager: DataManager):
        super().__init__(data_manager, "taxes", TaxDefinition)

# --- EKLENEN SINIF ---
class TaxProfileManager(BaseManager):
    def __init__(self, data_manager: DataManager):
        super().__init__(data_manager, "tax_profiles", TaxProfile)

# --- EKLENEN SINIF ---
class TaxProfileItemManager(BaseManager):
    def __init__(self, data_manager: DataManager):
        super().__init__(data_manager, "tax_profile_items", TaxProfileItem)

class TaxApplicationManager(BaseManager):
    def __init__(self, data_manager: DataManager):
        super().__init__(data_manager, "tax_applications", TaxApplication)

class TaxEngine:
    SNAPSHOT_VERSION = 2

    def __init__(self, data_manager: DataManager):
        self.data_manager = data_manager
        self.db = data_manager.db
        self.profile_id = data_manager.profile_id

    def compute_snapshot(
        self,
        items: List[Dict[str, Any]],
        currency: str,
        # selected_taxes ARTIK ID DEĞİL, LİSTE OLARAK GELİYOR
        selected_taxes: List[Dict[str, Any]], 
        *,
        customer_name: str = "",
        note: str = "",
        # Geriye dönük uyumluluk için (kullanılmıyor ama parametre hatası vermesin)
        tax_profile_id: Optional[str] = None, 
        apply_taxes: bool = True
    ) -> Dict[str, Any]:
        """
        Vergileri hesaplar. selected_taxes: [{'id': '...', 'rate': 20, 'type': 'percent', ...}]
        """
        clean_currency = (currency or "TRY").strip() or "TRY"

        # 1. Satırları hazırla
        lines: List[Dict[str, Any]] = []
        subtotal = Decimal("0")
        for it in items or []:
            name = str(it.get("name", "") or "").strip()
            qty = _to_decimal(it.get("qty"), default=Decimal("0"))
            unit_price = _to_decimal(it.get("unit_price"), default=Decimal("0"))
            line_subtotal = _money(qty * unit_price)
            subtotal += line_subtotal
            lines.append({
                "name": name,
                "qty": float(qty),
                "unit_price": float(_money(unit_price)),
                "line_subtotal": float(line_subtotal),
            })

        # 2. Vergileri ayır
        percent_taxes = []
        fixed_taxes = []
        
        # Eğer checkbox seçili değilse vergi listesini boşalt
        if not apply_taxes:
            selected_taxes = []

        for t in selected_taxes or []:
            if str(t.get("type")).lower() == "fixed":
                fixed_taxes.append(t)
            else:
                percent_taxes.append(t)

        taxes_breakdown: List[Dict[str, Any]] = []
        percent_totals: Dict[str, Decimal] = {str(t.get("id")): Decimal("0") for t in percent_taxes}

        # 3. Yüzde Vergileri Hesapla (Satır bazlı)
        percent_tax_total = Decimal("0")
        for line in lines:
            line_tax_total = Decimal("0")
            line_subtotal = _to_decimal(line.get("line_subtotal"), default=Decimal("0"))
            line_tax_items: List[Dict[str, Any]] = []
            
            for t in percent_taxes:
                tax_id = str(t.get("id"))
                rate = _to_decimal(t.get("rate"), default=Decimal("0"))
                amt = _money(line_subtotal * rate / Decimal("100"))
                if amt != 0:
                    line_tax_items.append({"tax_id": tax_id, "amount": float(amt)})
                percent_totals[tax_id] += amt
                line_tax_total += amt
            
            percent_tax_total += line_tax_total
            line_total = _money(line_subtotal + line_tax_total)
            line["line_tax_total"] = float(_money(line_tax_total))
            line["line_total"] = float(line_total)
            line["tax_items"] = line_tax_items

        # 4. Sabit Vergileri Hesapla (Genel toplama eklenir)
        fixed_tax_total = Decimal("0")
        fixed_items: List[Dict[str, Any]] = []
        for t in fixed_taxes:
            tax_id = str(t.get("id"))
            amt = _money(_to_decimal(t.get("rate"), default=Decimal("0")))
            fixed_tax_total += amt
            fixed_items.append({"tax_id": tax_id, "amount": float(amt)})
            taxes_breakdown.append({
                "tax_id": tax_id, "name": t.get("name"), "type": "fixed", 
                "rate": float(t.get("rate", 0)), "amount": float(amt)
            })

        # Yüzde dökümünü ekle
        for t in percent_taxes:
            tax_id = str(t.get("id"))
            amt = percent_totals.get(tax_id, Decimal("0"))
            taxes_breakdown.append({
                "tax_id": tax_id, "name": t.get("name"), "type": "percent", 
                "rate": float(t.get("rate", 0)), "amount": float(amt)
            })

        final_tax_total = percent_tax_total + fixed_tax_total
        grand_total = subtotal + final_tax_total

        return {
            "version": self.SNAPSHOT_VERSION,
            "apply_taxes": bool(selected_taxes) and apply_taxes,
            "currency": clean_currency,
            "customer_name": (customer_name or "").strip(),
            "note": (note or "").strip(),
            "subtotal": float(_money(subtotal)),
            "tax_total": float(_money(final_tax_total)),
            "grand_total": float(_money(grand_total)),
            "applied_taxes_summary": ", ".join([t.get("name", "") for t in selected_taxes]),
            "taxes": taxes_breakdown,
            "fixed_items": fixed_items,
            "lines": lines,
        }

    def create_tax_application_payload(
        self,
        *,
        source_table: str,
        source_id: str,
        snapshot: Dict[str, Any],
        tax_application_id: Optional[str] = None,
    ) -> TaxApplication:
        tax_app_id = tax_application_id or str(uuid.uuid4())
        currency = str(snapshot.get("currency") or "TRY")
        return TaxApplication(
            id=tax_app_id,
            source_table=source_table,
            source_id=source_id,
            subtotal=float(snapshot.get("subtotal") or 0),
            tax_total=float(snapshot.get("tax_total") or 0),
            grand_total=float(snapshot.get("grand_total") or 0),
            currency=currency,
            snapshot_json=snapshot,
            profile_id=self.profile_id,
        )



