"""
Routes for financial audit trail access.
"""
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from typing import Optional
from datetime import datetime
from ...shared.config.database import get_db
from ...shared.config.logging_config import get_logger
from ...security.middleware.auth import authorize_roles
from ...auth.models.user import User
from ..models.financial_audit_trail import FinancialAuditTrail, FinancialActionType
from ..services.financial_audit_service import financial_audit_service
from ...shared.utils.response_helpers import success_response

logger = get_logger(__name__)
router = APIRouter(prefix='/financial/audit-trail', tags=['financial-audit'])


@router.get('/')
async def get_financial_audit_trail(
    payment_id: Optional[int] = Query(None),
    invoice_id: Optional[int] = Query(None),
    booking_id: Optional[int] = Query(None),
    action_type: Optional[str] = Query(None),
    user_id: Optional[int] = Query(None),
    start_date: Optional[str] = Query(None),
    end_date: Optional[str] = Query(None),
    page: int = Query(1, ge=1),
    limit: int = Query(100, ge=1, le=1000),
    current_user: User = Depends(authorize_roles('admin', 'accountant')),
    db: Session = Depends(get_db)
):
    """Get financial audit trail records with filters."""
    try:
        # Parse dates
        start = None
        end = None
        if start_date:
            start = datetime.fromisoformat(start_date.replace('Z', '+00:00'))
        if end_date:
            end = datetime.fromisoformat(end_date.replace('Z', '+00:00'))
        
        # Parse action type
        action_type_enum = None
        if action_type:
            try:
                action_type_enum = FinancialActionType(action_type)
            except ValueError:
                raise HTTPException(status_code=400, detail=f'Invalid action_type: {action_type}')
        
        # Calculate offset
        offset = (page - 1) * limit
        
        # Get audit trail
        records = financial_audit_service.get_audit_trail(
            db=db,
            payment_id=payment_id,
            invoice_id=invoice_id,
            booking_id=booking_id,
            action_type=action_type_enum,
            user_id=user_id,
            start_date=start,
            end_date=end,
            limit=limit,
            offset=offset
        )
        
        # Format response
        audit_data = []
        for record in records:
            audit_data.append({
                'id': record.id,
                'action_type': record.action_type.value,
                'action_description': record.action_description,
                'payment_id': record.payment_id,
                'invoice_id': record.invoice_id,
                'booking_id': record.booking_id,
                'amount': float(record.amount) if record.amount else None,
                'previous_amount': float(record.previous_amount) if record.previous_amount else None,
                'currency': record.currency,
                'performed_by': record.performed_by,
                'performed_by_email': record.performed_by_email,
                'metadata': record.audit_metadata,
                'notes': record.notes,
                'created_at': record.created_at.isoformat() if record.created_at else None
            })
        
        # Get total count for pagination
        total_query = db.query(FinancialAuditTrail)
        if payment_id:
            total_query = total_query.filter(FinancialAuditTrail.payment_id == payment_id)
        if invoice_id:
            total_query = total_query.filter(FinancialAuditTrail.invoice_id == invoice_id)
        if booking_id:
            total_query = total_query.filter(FinancialAuditTrail.booking_id == booking_id)
        if action_type_enum:
            total_query = total_query.filter(FinancialAuditTrail.action_type == action_type_enum)
        if user_id:
            total_query = total_query.filter(FinancialAuditTrail.performed_by == user_id)
        if start:
            total_query = total_query.filter(FinancialAuditTrail.created_at >= start)
        if end:
            total_query = total_query.filter(FinancialAuditTrail.created_at <= end)
        
        total_count = total_query.count()
        total_pages = (total_count + limit - 1) // limit
        
        return success_response(
            data={
                'audit_trail': audit_data,
                'pagination': {
                    'page': page,
                    'limit': limit,
                    'total': total_count,
                    'total_pages': total_pages
                }
            },
            message='Financial audit trail retrieved successfully'
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f'Error retrieving financial audit trail: {str(e)}', exc_info=True)
        raise HTTPException(status_code=500, detail='An error occurred while retrieving audit trail')


@router.get('/{record_id}')
async def get_audit_record(
    record_id: int,
    current_user: User = Depends(authorize_roles('admin', 'accountant')),
    db: Session = Depends(get_db)
):
    """Get a specific audit trail record."""
    try:
        record = db.query(FinancialAuditTrail).filter(FinancialAuditTrail.id == record_id).first()
        if not record:
            raise HTTPException(status_code=404, detail='Audit record not found')
        
        return success_response(
            data={
                'id': record.id,
                'action_type': record.action_type.value,
                'action_description': record.action_description,
                'payment_id': record.payment_id,
                'invoice_id': record.invoice_id,
                'booking_id': record.booking_id,
                'amount': float(record.amount) if record.amount else None,
                'previous_amount': float(record.previous_amount) if record.previous_amount else None,
                'currency': record.currency,
                'performed_by': record.performed_by,
                'performed_by_email': record.performed_by_email,
                'metadata': record.audit_metadata,
                'notes': record.notes,
                'created_at': record.created_at.isoformat() if record.created_at else None
            },
            message='Audit record retrieved successfully'
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f'Error retrieving audit record: {str(e)}', exc_info=True)
        raise HTTPException(status_code=500, detail='An error occurred while retrieving audit record')

