from typing import List, Optional, Any, Dict
from sqlalchemy.orm import Session
from api.v1.modules.a76.app_settings.service import AppSettingsService
from api.v1.modules.a76.invoice_settings.dto import InvoiceSettingsRequest, OperationType

def get_settings(
    db: Session,
    tenant_id: int,
    company_id: int,
    invoice_type: str,
    operation_type: OperationType
) -> Optional[Dict[str, Any]]:
    """Retrieve settings for a specific context from app_settings"""
    # Use AppSettingsService to get the unifed settings
    app_settings = AppSettingsService.get_resolved_settings(db, tenant_id, company_id)
    if not app_settings:
        return None
    
    # Navigate to: invoices -> types -> {operation_type} -> {invoice_type}
    invoices = app_settings.get("invoices", {})
    types_map = invoices.get("types", {})
    op_map = types_map.get(operation_type.value, {})
    settings_payload = op_map.get(invoice_type)
    
    if settings_payload is None:
        return None
        
    return {
        "id": 0, # Virtual ID for compatibility
        "tenant_id": tenant_id,
        "company_id": company_id,
        "invoice_type": invoice_type,
        "operation_type": operation_type,
        "settings": settings_payload
    }

def list_settings(
    db: Session,
    tenant_id: int,
    company_id: int
) -> List[Dict[str, Any]]:
    """List all settings for a company from app_settings"""
    app_settings = AppSettingsService.get_resolved_settings(db, tenant_id, company_id)
    if not app_settings:
        return []
        
    invoices = app_settings.get("invoices", {})
    types_map = invoices.get("types", {})
    
    results = []
    for op_val, op_map in types_map.items():
        for inv_type, settings_payload in op_map.items():
            results.append({
                "id": 0,
                "tenant_id": tenant_id,
                "company_id": company_id,
                "invoice_type": inv_type,
                "operation_type": op_val,
                "settings": settings_payload
            })
    return results

def upsert_settings(
    db: Session,
    tenant_id: int,
    company_id: int,
    settings_data: InvoiceSettingsRequest
) -> Dict[str, Any]:
    """Create or update settings in app_settings"""
    # Construct the nested structure for AppSettingsService.upsert_settings
    # We use deep_merge in AppSettingsService, so we just send the branch we want to update
    payload = {
        "invoices": {
            "types": {
                settings_data.operation_type.value: {
                    settings_data.invoice_type: settings_data.settings
                }
            }
        }
    }
    
    # Save using the unified service
    AppSettingsService.upsert_settings(
        db,
        tenant_id=tenant_id,
        company_id=company_id,
        settings=payload
    )
    
    # Return the same structure as get_settings for consistency
    return {
        "id": 0,
        "tenant_id": tenant_id,
        "company_id": company_id,
        "invoice_type": settings_data.invoice_type,
        "operation_type": settings_data.operation_type,
        "settings": settings_data.settings
    }
