"""
Complaints utility functions

Export and bulk operation utilities.
"""
import csv
import io
from datetime import datetime
from typing import List

from django.http import HttpResponse
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment


def export_complaints_csv(queryset, filters=None):
    """
    Export complaints to CSV format.
    
    Args:
        queryset: Complaint queryset to export
        filters: Optional dict of applied filters
    
    Returns:
        HttpResponse with CSV file
    """
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = f'attachment; filename="complaints_{datetime.now().strftime("%Y%m%d_%H%M%S")}.csv"'
    
    writer = csv.writer(response)
    
    # Write header
    writer.writerow([
        'ID',
        'Title',
        'Patient Name',
        'Patient MRN',
        'Hospital',
        'Department',
        'Category',
        'Severity',
        'Priority',
        'Status',
        'Source',
        'Assigned To',
        'Created At',
        'Due At',
        'Is Overdue',
        'Resolved At',
        'Closed At',
        'Description',
    ])
    
    # Write data
    for complaint in queryset:
        writer.writerow([
            str(complaint.id)[:8],
            complaint.title,
            complaint.patient.get_full_name(),
            complaint.patient.mrn,
            complaint.hospital.name_en,
            complaint.department.name_en if complaint.department else '',
            complaint.get_category_display(),
            complaint.get_severity_display(),
            complaint.get_priority_display(),
            complaint.get_status_display(),
            complaint.get_source_display(),
            complaint.assigned_to.get_full_name() if complaint.assigned_to else '',
            complaint.created_at.strftime('%Y-%m-%d %H:%M:%S'),
            complaint.due_at.strftime('%Y-%m-%d %H:%M:%S'),
            'Yes' if complaint.is_overdue else 'No',
            complaint.resolved_at.strftime('%Y-%m-%d %H:%M:%S') if complaint.resolved_at else '',
            complaint.closed_at.strftime('%Y-%m-%d %H:%M:%S') if complaint.closed_at else '',
            complaint.description[:500],
        ])
    
    return response


def export_complaints_excel(queryset, filters=None):
    """
    Export complaints to Excel format with formatting.
    
    Args:
        queryset: Complaint queryset to export
        filters: Optional dict of applied filters
    
    Returns:
        HttpResponse with Excel file
    """
    wb = Workbook()
    ws = wb.active
    ws.title = "Complaints"
    
    # Define styles
    header_font = Font(bold=True, color="FFFFFF")
    header_fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid")
    header_alignment = Alignment(horizontal="center", vertical="center")
    
    # Write header
    headers = [
        'ID', 'Title', 'Patient Name', 'Patient MRN', 'Hospital', 'Department',
        'Category', 'Severity', 'Priority', 'Status', 'Source', 'Assigned To',
        'Created At', 'Due At', 'Is Overdue', 'Resolved At', 'Closed At', 'Description'
    ]
    
    for col_num, header in enumerate(headers, 1):
        cell = ws.cell(row=1, column=col_num, value=header)
        cell.font = header_font
        cell.fill = header_fill
        cell.alignment = header_alignment
    
    # Write data
    for row_num, complaint in enumerate(queryset, 2):
        ws.cell(row=row_num, column=1, value=str(complaint.id)[:8])
        ws.cell(row=row_num, column=2, value=complaint.title)
        ws.cell(row=row_num, column=3, value=complaint.patient.get_full_name())
        ws.cell(row=row_num, column=4, value=complaint.patient.mrn)
        ws.cell(row=row_num, column=5, value=complaint.hospital.name_en)
        ws.cell(row=row_num, column=6, value=complaint.department.name_en if complaint.department else '')
        ws.cell(row=row_num, column=7, value=complaint.get_category_display())
        ws.cell(row=row_num, column=8, value=complaint.get_severity_display())
        ws.cell(row=row_num, column=9, value=complaint.get_priority_display())
        ws.cell(row=row_num, column=10, value=complaint.get_status_display())
        ws.cell(row=row_num, column=11, value=complaint.get_source_display())
        ws.cell(row=row_num, column=12, value=complaint.assigned_to.get_full_name() if complaint.assigned_to else '')
        ws.cell(row=row_num, column=13, value=complaint.created_at.strftime('%Y-%m-%d %H:%M:%S'))
        ws.cell(row=row_num, column=14, value=complaint.due_at.strftime('%Y-%m-%d %H:%M:%S'))
        ws.cell(row=row_num, column=15, value='Yes' if complaint.is_overdue else 'No')
        ws.cell(row=row_num, column=16, value=complaint.resolved_at.strftime('%Y-%m-%d %H:%M:%S') if complaint.resolved_at else '')
        ws.cell(row=row_num, column=17, value=complaint.closed_at.strftime('%Y-%m-%d %H:%M:%S') if complaint.closed_at else '')
        ws.cell(row=row_num, column=18, value=complaint.description[:500])
    
    # Auto-adjust column widths
    for column in ws.columns:
        max_length = 0
        column_letter = column[0].column_letter
        for cell in column:
            try:
                if len(str(cell.value)) > max_length:
                    max_length = len(cell.value)
            except:
                pass
        adjusted_width = min(max_length + 2, 50)
        ws.column_dimensions[column_letter].width = adjusted_width
    
    # Save to response
    response = HttpResponse(
        content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    )
    response['Content-Disposition'] = f'attachment; filename="complaints_{datetime.now().strftime("%Y%m%d_%H%M%S")}.xlsx"'
    wb.save(response)
    
    return response


def bulk_assign_complaints(complaint_ids: List[str], user_id: str, current_user):
    """
    Bulk assign complaints to a user.
    
    Args:
        complaint_ids: List of complaint IDs
        user_id: ID of user to assign to
        current_user: User performing the action
    
    Returns:
        dict: Result with success count and errors
    """
    from apps.complaints.models import Complaint, ComplaintUpdate
    from apps.accounts.models import User
    from django.utils import timezone
    
    try:
        assignee = User.objects.get(id=user_id)
    except User.DoesNotExist:
        return {'success': False, 'error': 'User not found'}
    
    success_count = 0
    errors = []
    
    for complaint_id in complaint_ids:
        try:
            complaint = Complaint.objects.get(id=complaint_id)
            complaint.assigned_to = assignee
            complaint.assigned_at = timezone.now()
            complaint.save(update_fields=['assigned_to', 'assigned_at'])
            
            # Create update
            ComplaintUpdate.objects.create(
                complaint=complaint,
                update_type='assignment',
                message=f"Bulk assigned to {assignee.get_full_name()}",
                created_by=current_user
            )
            
            success_count += 1
        except Complaint.DoesNotExist:
            errors.append(f"Complaint {complaint_id} not found")
        except Exception as e:
            errors.append(f"Error assigning complaint {complaint_id}: {str(e)}")
    
    return {
        'success': True,
        'success_count': success_count,
        'total': len(complaint_ids),
        'errors': errors
    }


def bulk_change_status(complaint_ids: List[str], new_status: str, current_user, note: str = ''):
    """
    Bulk change status of complaints.
    
    Args:
        complaint_ids: List of complaint IDs
        new_status: New status to set
        current_user: User performing the action
        note: Optional note
    
    Returns:
        dict: Result with success count and errors
    """
    from apps.complaints.models import Complaint, ComplaintUpdate
    from django.utils import timezone
    
    success_count = 0
    errors = []
    
    for complaint_id in complaint_ids:
        try:
            complaint = Complaint.objects.get(id=complaint_id)
            old_status = complaint.status
            complaint.status = new_status
            
            # Handle status-specific logic
            if new_status == 'resolved':
                complaint.resolved_at = timezone.now()
                complaint.resolved_by = current_user
            elif new_status == 'closed':
                complaint.closed_at = timezone.now()
                complaint.closed_by = current_user
            
            complaint.save()
            
            # Create update
            ComplaintUpdate.objects.create(
                complaint=complaint,
                update_type='status_change',
                message=note or f"Bulk status change from {old_status} to {new_status}",
                created_by=current_user,
                old_status=old_status,
                new_status=new_status
            )
            
            success_count += 1
        except Complaint.DoesNotExist:
            errors.append(f"Complaint {complaint_id} not found")
        except Exception as e:
            errors.append(f"Error changing status for complaint {complaint_id}: {str(e)}")
    
    return {
        'success': True,
        'success_count': success_count,
        'total': len(complaint_ids),
        'errors': errors
    }


def bulk_escalate_complaints(complaint_ids: List[str], current_user, reason: str = ''):
    """
    Bulk escalate complaints.
    
    Args:
        complaint_ids: List of complaint IDs
        current_user: User performing the action
        reason: Escalation reason
    
    Returns:
        dict: Result with success count and errors
    """
    from apps.complaints.models import Complaint, ComplaintUpdate
    from django.utils import timezone
    
    success_count = 0
    errors = []
    
    for complaint_id in complaint_ids:
        try:
            complaint = Complaint.objects.get(id=complaint_id)
            complaint.escalated_at = timezone.now()
            complaint.save(update_fields=['escalated_at'])
            
            # Create update
            ComplaintUpdate.objects.create(
                complaint=complaint,
                update_type='escalation',
                message=f"Bulk escalation. Reason: {reason or 'No reason provided'}",
                created_by=current_user
            )
            
            success_count += 1
        except Complaint.DoesNotExist:
            errors.append(f"Complaint {complaint_id} not found")
        except Exception as e:
            errors.append(f"Error escalating complaint {complaint_id}: {str(e)}")
    
    return {
        'success': True,
        'success_count': success_count,
        'total': len(complaint_ids),
        'errors': errors
    }
