from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from django.http import HttpResponse
from django.db.models import Sum, Count
from django.db.models.functions import TruncMonth, TruncDate
from datetime import date
from finance.models import Contribution
from members.models import Member
from reportlab.lib.pagesizes import A4
from reportlab.platypus import (
    SimpleDocTemplate, Table, TableStyle,
    Paragraph, Spacer
)
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import cm
import openpyxl
from openpyxl.styles import Font, PatternFill, Alignment


def get_contributions(start_date=None, end_date=None, member_id=None):
    qs = Contribution.objects.select_related(
        'member', 'contribution_type', 'payment_method'
    ).filter(status='completed')
    if start_date:
        qs = qs.filter(date__gte=start_date)
    if end_date:
        qs = qs.filter(date__lte=end_date)
    if member_id:
        qs = qs.filter(member_id=member_id)
    return qs


class ReportSummaryView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        start = request.query_params.get('start_date')
        end = request.query_params.get('end_date')
        member_id = request.query_params.get('member')

        qs = get_contributions(start, end, member_id)
        total = qs.aggregate(total=Sum('amount'))['total'] or 0
        count = qs.count()

        by_type = qs.values(
            'contribution_type__name'
        ).annotate(
            total=Sum('amount'), count=Count('id')
        )

        by_method = qs.values(
            'payment_method__name'
        ).annotate(
            total=Sum('amount'), count=Count('id')
        )

        by_month = qs.annotate(
            month=TruncMonth('date')
        ).values('month').annotate(
            total=Sum('amount'), count=Count('id')
        ).order_by('month')

        return Response({
            'total': total,
            'count': count,
            'by_type': list(by_type),
            'by_method': list(by_method),
            'by_month': list(by_month),
        })


class ExportPDFView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        start = request.query_params.get('start_date')
        end = request.query_params.get('end_date')
        member_id = request.query_params.get('member')
        report_type = request.query_params.get('type', 'general')

        qs = get_contributions(start, end, member_id)
        title = f"CFC Church — Contributions Report"
        if start and end:
            title += f" ({start} to {end})"

        response = HttpResponse(content_type='application/pdf')
        response['Content-Disposition'] = f'attachment; filename="contributions_report.pdf"'

        doc = SimpleDocTemplate(
            response, pagesize=A4,
            rightMargin=2*cm, leftMargin=2*cm,
            topMargin=2*cm, bottomMargin=2*cm
        )
        styles = getSampleStyleSheet()
        elements = []

        # Title
        elements.append(Paragraph(title, styles['Title']))
        elements.append(Paragraph(
            f"Generated on: {date.today().strftime('%d %B %Y')}",
            styles['Normal']
        ))
        elements.append(Spacer(1, 0.5*cm))

        # Summary
        total = qs.aggregate(total=Sum('amount'))['total'] or 0
        elements.append(Paragraph(
            f"Total Contributions: KES {total:,.2f} | Records: {qs.count()}",
            styles['Normal']
        ))
        elements.append(Spacer(1, 0.5*cm))

        # Table
        table_data = [['#', 'Member', 'Amount (KES)', 'Type', 'Method', 'Receipt', 'Date']]
        for i, c in enumerate(qs, 1):
            table_data.append([
                str(i),
                c.member.full_name if c.member else 'Unknown',
                f"{c.amount:,.2f}",
                c.contribution_type.name,
                c.payment_method.name,
                c.mpesa_receipt or c.reference_number or '-',
                c.date.strftime('%d/%m/%Y'),
            ])

        # Totals row
        table_data.append(['', 'TOTAL', f"KES {total:,.2f}", '', '', '', ''])

        table = Table(table_data, repeatRows=1)
        table.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#1D9E75')),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
            ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
            ('FONTSIZE', (0, 0), (-1, 0), 10),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('ALIGN', (1, 1), (1, -1), 'LEFT'),
            ('BACKGROUND', (0, -1), (-1, -1), colors.HexColor('#E1F5EE')),
            ('FONTNAME', (0, -1), (-1, -1), 'Helvetica-Bold'),
            ('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
            ('ROWBACKGROUNDS', (0, 1), (-1, -2), [
                colors.white, colors.HexColor('#F8FFFE')
            ]),
            ('FONTSIZE', (0, 1), (-1, -1), 8),
        ]))
        elements.append(table)
        doc.build(elements)
        return response


class ExportExcelView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        start = request.query_params.get('start_date')
        end = request.query_params.get('end_date')
        member_id = request.query_params.get('member')

        qs = get_contributions(start, end, member_id)

        response = HttpResponse(
            content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        response['Content-Disposition'] = 'attachment; filename="contributions_report.xlsx"'

        wb = openpyxl.Workbook()
        ws = wb.active
        ws.title = "Contributions"

        # Header styling
        header_fill = PatternFill("solid", fgColor="1D9E75")
        header_font = Font(bold=True, color="FFFFFF")
        total_fill = PatternFill("solid", fgColor="E1F5EE")
        total_font = Font(bold=True)

        headers = ['#', 'Member ID', 'Member Name', 'Amount (KES)',
                   'Type', 'Method', 'Receipt/Ref', 'Date', 'Notes']
        ws.append(headers)

        for cell in ws[1]:
            cell.fill = header_fill
            cell.font = header_font
            cell.alignment = Alignment(horizontal='center')

        # Data rows
        total = 0
        for i, c in enumerate(qs, 1):
            ws.append([
                i,
                c.member.member_id if c.member else '-',
                c.member.full_name if c.member else 'Unknown',
                float(c.amount),
                c.contribution_type.name,
                c.payment_method.name,
                c.mpesa_receipt or c.reference_number or '-',
                c.date.strftime('%d/%m/%Y'),
                c.notes or '-',
            ])
            total += c.amount

        # Total row
        total_row = ['', '', 'TOTAL', float(total), '', '', '', '', '']
        ws.append(total_row)
        for cell in ws[ws.max_row]:
            cell.fill = total_fill
            cell.font = total_font

        # Column widths
        col_widths = [5, 12, 25, 15, 15, 15, 20, 12, 20]
        for i, width in enumerate(col_widths, 1):
            ws.column_dimensions[
                openpyxl.utils.get_column_letter(i)
            ].width = width

        wb.save(response)
        return response