from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.http import HttpResponse
from django.utils.timezone import now
from django.db.models import Q
from openpyxl import Workbook

from .models import Student, Attendance, FeePayment


def _current_month_str():
    return now().strftime('%Y-%m')


# ------------------------------------------------------------------ #
# STUDENT LIST
# ------------------------------------------------------------------ #
@login_required(login_url='/login/')
def student_list(request):
    org = request.user.org
    if not org:
        return redirect('landing')

    q = request.GET.get('q', '').strip()
    students = Student.objects.filter(org=org)
    if q:
        students = students.filter(
            Q(name__icontains=q) | Q(phone__icontains=q) | Q(batch_or_class__icontains=q)
        )

    show_inactive = request.GET.get('inactive') == '1'
    if not show_inactive:
        students = students.filter(is_active=True)

    month = _current_month_str()
    student_rows = []
    for s in students:
        student_rows.append({
            'obj':        s,
            'fee_amount': s.effective_monthly_fee(),
            'fee_paid':   s.fee_status_for_month(month),
        })

    return render(request, 'students/list.html', {
        'org':      org,
        'students': student_rows,
        'q':        q,
        'month':    month,
        'show_inactive': show_inactive,
    })


# ------------------------------------------------------------------ #
# ADD / EDIT STUDENT
# ------------------------------------------------------------------ #
@login_required(login_url='/login/')
def student_add(request):
    org = request.user.org
    if not org:
        return redirect('landing')

    if request.method == 'POST':
        name = request.POST.get('name', '').strip()
        if not name:
            messages.error(request, 'Name is required.')
            return render(request, 'students/form.html', {'org': org})

        fee_raw = request.POST.get('monthly_fee', '').strip()
        Student.objects.create(
            org            = org,
            name           = name,
            dob            = request.POST.get('dob', '').strip(),
            gender         = request.POST.get('gender', '').strip(),
            guardian_name  = request.POST.get('guardian_name', '').strip(),
            phone          = request.POST.get('phone', '').strip(),
            email          = request.POST.get('email', '').strip(),
            address        = request.POST.get('address', '').strip(),
            batch_or_class = request.POST.get('batch_or_class', '').strip(),
            monthly_fee    = int(fee_raw) if fee_raw.isdigit() else None,
            added_via_qr   = False,
        )
        messages.success(request, f'{name} added.')
        return redirect('student_list')

    return render(request, 'students/form.html', {'org': org})


@login_required(login_url='/login/')
def student_edit(request, pk):
    org = request.user.org
    student = get_object_or_404(Student, pk=pk, org=org)

    if request.method == 'POST':
        student.name           = request.POST.get('name', student.name).strip()
        student.dob            = request.POST.get('dob', '').strip()
        student.gender         = request.POST.get('gender', '').strip()
        student.guardian_name  = request.POST.get('guardian_name', '').strip()
        student.phone          = request.POST.get('phone', '').strip()
        student.email          = request.POST.get('email', '').strip()
        student.address        = request.POST.get('address', '').strip()
        student.batch_or_class = request.POST.get('batch_or_class', '').strip()

        fee_raw = request.POST.get('monthly_fee', '').strip()
        student.monthly_fee = int(fee_raw) if fee_raw.isdigit() else None
        student.is_active   = request.POST.get('is_active') == 'on'
        student.save()

        messages.success(request, f'{student.name} updated.')
        return redirect('student_list')

    return render(request, 'students/form.html', {'org': org, 'student': student})


@login_required(login_url='/login/')
def student_detail(request, pk):
    org = request.user.org
    student = get_object_or_404(Student, pk=pk, org=org)

    attendance = student.attendance_records.all()[:60]
    payments   = student.fee_payments.all()[:24]

    return render(request, 'students/detail.html', {
        'org':        org,
        'student':    student,
        'attendance': attendance,
        'payments':   payments,
        'this_month': _current_month_str(),
    })


# ------------------------------------------------------------------ #
# ATTENDANCE REPORT
# ------------------------------------------------------------------ #
@login_required(login_url='/login/')
def attendance_report(request):
    org = request.user.org
    if not org:
        return redirect('landing')

    from_date = request.GET.get('from_date', '')
    to_date   = request.GET.get('to_date', '')

    records = Attendance.objects.filter(org=org).select_related('student')
    if from_date:
        records = records.filter(date__gte=from_date)
    if to_date:
        records = records.filter(date__lte=to_date)

    present_today = Attendance.objects.filter(
        org=org, date=Attendance.attendance_date_for(now()), event='IN'
    ).values('student').distinct().count()

    return render(request, 'students/attendance_report.html', {
        'org':           org,
        'records':       records[:500],
        'from_date':     from_date,
        'to_date':       to_date,
        'present_today': present_today,
        'total_students': Student.objects.filter(org=org, is_active=True).count(),
    })


@login_required(login_url='/login/')
def attendance_export(request):
    org = request.user.org
    if not org:
        return redirect('landing')

    from_date = request.GET.get('from_date', '')
    to_date   = request.GET.get('to_date', '')

    records = Attendance.objects.filter(org=org).select_related('student')
    if from_date:
        records = records.filter(date__gte=from_date)
    if to_date:
        records = records.filter(date__lte=to_date)

    wb = Workbook()
    ws = wb.active
    ws.title = 'Attendance'
    ws.append(['Student', 'Class/Batch', 'Date', 'Event', 'Time'])

    for r in records:
        ws.append([r.student.name, r.student.batch_or_class, str(r.date), r.event, str(r.timestamp)])

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


# ------------------------------------------------------------------ #
# FEE REPORT
# ------------------------------------------------------------------ #
@login_required(login_url='/login/')
def fee_report(request):
    org = request.user.org
    if not org:
        return redirect('landing')

    month = request.GET.get('month', _current_month_str())
    students = Student.objects.filter(org=org, is_active=True)

    rows = []
    total_collected = 0
    total_pending   = 0
    for s in students:
        amount = s.effective_monthly_fee()
        paid   = s.fee_status_for_month(month)
        rows.append({'student': s, 'amount': amount, 'paid': paid})
        if paid:
            total_collected += amount
        else:
            total_pending += amount

    return render(request, 'students/fee_report.html', {
        'org':             org,
        'rows':            rows,
        'month':           month,
        'total_collected': total_collected,
        'total_pending':   total_pending,
    })


@login_required(login_url='/login/')
def fee_mark_paid(request, pk):
    org = request.user.org
    student = get_object_or_404(Student, pk=pk, org=org)

    if request.method == 'POST':
        month  = request.POST.get('month', _current_month_str())
        amount = request.POST.get('amount', '').strip()
        method = request.POST.get('method', '').strip()

        try:
            amount_val = int(amount) if amount else student.effective_monthly_fee()
        except ValueError:
            amount_val = student.effective_monthly_fee()

        FeePayment.objects.update_or_create(
            student=student, month=month,
            defaults={
                'org':         org,
                'amount':      amount_val,
                'method':      method,
                'recorded_by': request.user.email if hasattr(request.user, 'email') else '',
            }
        )
        messages.success(request, f'Payment recorded for {student.name} ({month}).')

    return redirect(request.META.get('HTTP_REFERER', 'fee_report'))
