"""
Routes for compliance reporting and management.
"""
from fastapi import APIRouter, Depends, HTTPException, Query, Response
from sqlalchemy.orm import Session
from typing import Optional
from datetime import datetime, timedelta
import csv
import io
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 ...payments.models.financial_audit_trail import FinancialAuditTrail
from ...security.models.gdpr_compliance import DataSubjectRequest, DataSubjectRequestStatus
from ...analytics.models.audit_log import AuditLog
from ...shared.utils.response_helpers import success_response

logger = get_logger(__name__)
router = APIRouter(prefix='/compliance', tags=['compliance'])


@router.get('/report')
async def get_compliance_report(
    start_date: Optional[str] = Query(None),
    end_date: Optional[str] = Query(None),
    format: str = Query("json", regex="^(json|csv)$"),
    current_user: User = Depends(authorize_roles('admin', 'accountant')),
    db: Session = Depends(get_db)
):
    """Generate comprehensive compliance report."""
    try:
        # Parse dates
        if start_date:
            try:
                # Try parsing as full datetime first
                start = datetime.fromisoformat(start_date.replace('Z', '+00:00'))
            except ValueError:
                # If that fails, parse as date only
                start = datetime.strptime(start_date, '%Y-%m-%d')
        else:
            start = datetime.utcnow() - timedelta(days=30)
        
        if end_date:
            try:
                # Try parsing as full datetime first
                end = datetime.fromisoformat(end_date.replace('Z', '+00:00'))
            except ValueError:
                # If that fails, parse as date only, set to end of day
                end = datetime.strptime(end_date, '%Y-%m-%d').replace(hour=23, minute=59, second=59)
        else:
            end = datetime.utcnow()
        
        # Financial audit trail statistics
        try:
            financial_audits = db.query(FinancialAuditTrail).filter(
                FinancialAuditTrail.created_at >= start,
                FinancialAuditTrail.created_at <= end
            ).count()
        except Exception as e:
            logger.warning(f'Error querying financial audit trail: {str(e)}')
            financial_audits = 0
        
        # GDPR requests statistics
        try:
            gdpr_requests = db.query(DataSubjectRequest).filter(
                DataSubjectRequest.created_at >= start,
                DataSubjectRequest.created_at <= end
            ).count()
            
            gdpr_completed = db.query(DataSubjectRequest).filter(
                DataSubjectRequest.created_at >= start,
                DataSubjectRequest.created_at <= end,
                DataSubjectRequest.status == DataSubjectRequestStatus.completed
            ).count()
        except Exception as e:
            logger.warning(f'Error querying GDPR requests: {str(e)}')
            gdpr_requests = 0
            gdpr_completed = 0
        
        # Security audit logs
        try:
            security_audits = db.query(AuditLog).filter(
                AuditLog.created_at >= start,
                AuditLog.created_at <= end
            ).count()
        except Exception as e:
            logger.warning(f'Error querying security audit logs: {str(e)}')
            security_audits = 0
        
        # Build report
        report = {
            'period': {
                'start_date': start.isoformat(),
                'end_date': end.isoformat()
            },
            'financial_audit': {
                'total_actions': financial_audits,
                'description': 'Total financial transactions logged in audit trail'
            },
            'gdpr_compliance': {
                'total_requests': gdpr_requests,
                'completed_requests': gdpr_completed,
                'completion_rate': round((gdpr_completed / gdpr_requests * 100) if gdpr_requests > 0 else 0, 2),
                'description': 'GDPR data subject requests processed'
            },
            'security_audit': {
                'total_events': security_audits,
                'description': 'Total security audit events logged'
            },
            'compliance_status': 'compliant' if (gdpr_requests == 0 or gdpr_requests == gdpr_completed) else 'pending_review',
            'generated_at': datetime.utcnow().isoformat(),
            'generated_by': current_user.email if current_user.email else f'User {current_user.id}'
        }
        
        if format.lower() == 'csv':
            output = io.StringIO()
            writer = csv.writer(output)
            
            writer.writerow(['Compliance Report'])
            writer.writerow(['Period', f"{start.date()} to {end.date()}"])
            writer.writerow(['Generated At', datetime.utcnow().isoformat()])
            writer.writerow(['Generated By', current_user.email if current_user.email else f'User {current_user.id}'])
            writer.writerow([])
            
            writer.writerow(['Financial Audit'])
            writer.writerow(['Total Actions', financial_audits])
            writer.writerow([])
            
            writer.writerow(['GDPR Compliance'])
            writer.writerow(['Total Requests', gdpr_requests])
            writer.writerow(['Completed Requests', gdpr_completed])
            writer.writerow(['Completion Rate', f"{report['gdpr_compliance']['completion_rate']}%"])
            writer.writerow([])
            
            writer.writerow(['Security Audit'])
            writer.writerow(['Total Events', security_audits])
            writer.writerow([])
            
            writer.writerow(['Compliance Status', report['compliance_status']])
            
            return Response(
                content=output.getvalue(),
                media_type='text/csv',
                headers={
                    'Content-Disposition': f'attachment; filename="compliance_report_{datetime.utcnow().strftime("%Y%m%d")}.csv"'
                }
            )
        
        return success_response(
            data=report,
            message='Compliance report generated successfully'
        )
    except Exception as e:
        logger.error(f'Error generating compliance report: {str(e)}', exc_info=True)
        raise HTTPException(status_code=500, detail='An error occurred while generating compliance report')


@router.get('/gdpr-summary')
async def get_gdpr_summary(
    current_user: User = Depends(authorize_roles('admin')),
    db: Session = Depends(get_db)
):
    """Get GDPR compliance summary."""
    try:
        # Get statistics
        total_requests = db.query(DataSubjectRequest).count()
        pending_requests = db.query(DataSubjectRequest).filter(
            DataSubjectRequest.status == DataSubjectRequestStatus.pending
        ).count()
        completed_requests = db.query(DataSubjectRequest).filter(
            DataSubjectRequest.status == DataSubjectRequestStatus.completed
        ).count()
        
        # Requests by type
        from ...security.models.gdpr_compliance import DataSubjectRequestType
        requests_by_type = {}
        for req_type in DataSubjectRequestType:
            count = db.query(DataSubjectRequest).filter(
                DataSubjectRequest.request_type == req_type
            ).count()
            requests_by_type[req_type.value] = count
        
        return success_response(
            data={
                'total_requests': total_requests,
                'pending_requests': pending_requests,
                'completed_requests': completed_requests,
                'completion_rate': round((completed_requests / total_requests * 100) if total_requests > 0 else 0, 2),
                'requests_by_type': requests_by_type,
                'compliance_status': 'compliant' if pending_requests == 0 else 'pending_review'
            },
            message='GDPR compliance summary retrieved successfully'
        )
    except Exception as e:
        logger.error(f'Error retrieving GDPR summary: {str(e)}', exc_info=True)
        raise HTTPException(status_code=500, detail='An error occurred while retrieving GDPR summary')

