from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth import authenticate, login, logout
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth import get_user_model
from django.urls import reverse_lazy
from tenants.models import TenantProfile
from payments.models import Payment
from properties.models import Building
from django.db.models import Q, Sum
from .models import User
from .forms import TenantRegisterForm
from django.contrib.auth.views import PasswordChangeView, PasswordChangeDoneView
from django.utils.text import slugify
from django.utils import timezone
from .models import User
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from django.db.models import Sum, Q

from properties.models import Unit, Building
from payments.models import Invoice, Payment


User = get_user_model()


# ================= LOGIN =================
def login_view(request):
    if request.user.is_authenticated:
        return safe_redirect_user(request)

    if request.method == "POST":
        username = request.POST.get("username")
        password = request.POST.get("password")
        remember = request.POST.get("remember")  # ✅ NEW

        user = authenticate(request, username=username, password=password)

        if user:
            login(request, user)

            # ================= REMEMBER ME LOGIC =================
            if remember:
                request.session.set_expiry(1209600)  # 2 weeks
            else:
                request.session.set_expiry(0)  # close browser = logout

            messages.success(request, "Login successful")
            return safe_redirect_user(request)

        messages.error(request, "Invalid username or password")

    return render(request, "accounts/login.html")

# ================= LOGOUT =================
def logout_view(request):
    logout(request)
    messages.success(request, "You have been logged out")
    return redirect("login")


# ================= SAFE REDIRECT =================
def safe_redirect_user(request):
    user = request.user

    if user.is_first_login:
        return redirect("password_change")

    if user.role == "tenant":
        profile = TenantProfile.objects.filter(user=user).first()

        if profile and not profile.id_image:
            return redirect("tenant_onboarding")

        return redirect("tenant_dashboard")

    if user.role == "landlord":
        return redirect("landlord_dashboard")

    if user.role == "caretaker":
        return redirect("caretaker_dashboard")

    logout(request)
    return redirect("login")


# ================= DASHBOARDS =================

@login_required(login_url='login')
def landlord_dashboard(request):
    if request.user.role != "landlord":
        return redirect("login")

    buildings = Building.objects.filter(landlord=request.user)
    units = Unit.objects.filter(building__landlord=request.user)

    total_units = units.count()
    occupied_units = sum(1 for u in units if u.is_occupied)
    vacant_units = total_units - occupied_units

    # ================= FINANCIAL SUMMARY =================
    invoices = Invoice.objects.filter(unit__building__landlord=request.user)
    payments = Payment.objects.filter(unit__building__landlord=request.user)

    total_expected = invoices.aggregate(total=Sum("amount"))["total"] or 0
    total_paid = payments.aggregate(total=Sum("amount"))["total"] or 0
    total_balance = total_expected - total_paid

    # ================= RECENT ACTIVITY =================
    recent_units = units.order_by("-created_at")[:5]
    recent_payments = payments.order_by("-created_at")[:5]

    return render(request, "dashboards/landlord_dashboard.html", {
        "buildings": buildings,
        "units": units,

        "total_units": total_units,
        "occupied_units": occupied_units,
        "vacant_units": vacant_units,

        "total_expected": total_expected,
        "total_paid": total_paid,
        "total_balance": total_balance,

        "recent_units": recent_units,
        "recent_payments": recent_payments,
    })

@login_required(login_url='login')
def caretaker_dashboard(request):
    if request.user.role != "caretaker":
        return redirect("login")

    buildings = Building.objects.filter(caretaker=request.user)
    units = Unit.objects.filter(building__caretaker=request.user)

    total_units = units.count()
    occupied_units = sum(1 for u in units if u.is_occupied)
    vacant_units = total_units - occupied_units

    # ================= FINANCIAL SUMMARY =================
    invoices = Invoice.objects.filter(unit__building__caretaker=request.user)
    payments = Payment.objects.filter(unit__building__caretaker=request.user)

    total_expected = invoices.aggregate(total=Sum("amount"))["total"] or 0
    total_paid = payments.aggregate(total=Sum("amount"))["total"] or 0
    total_balance = total_expected - total_paid

    # ================= RECENT ACTIVITY =================
    recent_units = units.order_by("-created_at")[:5]
    recent_payments = payments.order_by("-created_at")[:5]

    return render(request, "dashboards/caretaker_dashboard.html", {
        "buildings": buildings,
        "units": units,

        "total_units": total_units,
        "occupied_units": occupied_units,
        "vacant_units": vacant_units,

        "total_expected": total_expected,
        "total_paid": total_paid,
        "total_balance": total_balance,

        "recent_units": recent_units,
        "recent_payments": recent_payments,
    })
@login_required
def tenant_dashboard(request):
    if request.user.role != "tenant":
        return redirect("login")

    today = timezone.now().date()

    invoices = request.user.invoices.filter(
        status__in=["pending", "partial", "overdue"]
    ).order_by("due_date")

    # 🔥 FORCE STATUS UPDATE (CRITICAL)
    for inv in invoices:
        inv.update_status()

    current_invoice = invoices.first()

    total_due = invoices.aggregate(
        total=Sum("amount")
    )["total"] or 0

    return render(request, "dashboards/tenant_dashboard.html", {
        "current_invoice": current_invoice,
        "total_due": total_due,
        "today": today,
    })

# ================= PASSWORD CHANGE =================
class CustomPasswordChangeView(PasswordChangeView):
    template_name = "accounts/password_change.html"

    def get_success_url(self):
        return reverse_lazy("password_change_done")

    def form_valid(self, form):
        response = super().form_valid(form)

        user = self.request.user
        if user.is_first_login:
            user.is_first_login = False
            user.save()

        return response


class CustomPasswordChangeDoneView(PasswordChangeDoneView):
    template_name = "accounts/password_change_done.html"

    def dispatch(self, request, *args, **kwargs):
        return safe_redirect_user(request)


# ================= CARETAKER =================
@login_required
def caretaker_list(request):
    if request.user.role != "landlord":
        return redirect("login")

    caretakers = User.objects.filter(role="caretaker")

    return render(request, "accounts/caretaker_list.html", {
        "caretakers": caretakers
    })


@login_required
def caretaker_create(request):
    if request.user.role != "landlord":
        return redirect("login")

    if request.method == "POST":
        first_name = (request.POST.get("first_name") or "").strip()
        last_name = (request.POST.get("last_name") or "").strip()
        phone_number = (request.POST.get("phone_number") or "").strip()
        id_number = (request.POST.get("id_number") or "").strip()

        # ================= VALIDATION =================
        if not first_name:
            messages.error(request, "First name is required")
            return redirect("caretaker_add")

        if not last_name:
            messages.error(request, "Last name is required")
            return redirect("caretaker_add")

        if not phone_number:
            messages.error(request, "Phone number is required")
            return redirect("caretaker_add")

        if not id_number:
            messages.error(request, "ID number is required")
            return redirect("caretaker_add")

        if User.objects.filter(phone_number=phone_number).exists():
            messages.error(request, "Phone number already exists")
            return redirect("caretaker_add")

        # ================= USERNAME GENERATION =================
        base_username = slugify(f"{first_name}.{last_name}")
        username = base_username
        counter = 1

        while User.objects.filter(username=username).exists():
            username = f"{base_username}{counter}"
            counter += 1

        # ================= CREATE USER =================
        user = User.objects.create(
            username=username,
            first_name=first_name,
            last_name=last_name,
            phone_number=phone_number,
            role="caretaker",
            is_first_login=True
        )

        # Password = ID number
        user.set_password(id_number)
        user.save()

        messages.success(request, "Caretaker created. Default password is ID number.")
        return redirect("caretaker_list")

    return render(request, "accounts/caretaker_form.html")

@login_required
def caretaker_update(request, user_id):
    caretaker = get_object_or_404(User, id=user_id, role="caretaker")

    if request.method == "POST":
        caretaker.username = request.POST.get("username")
        caretaker.phone_number = request.POST.get("phone_number")
        caretaker.save()

        messages.success(request, "Caretaker updated")
        return redirect("caretaker_list")

    return render(request, "accounts/caretaker_form.html", {
        "caretaker": caretaker
    })


@login_required
def caretaker_delete(request, user_id):
    caretaker = get_object_or_404(User, id=user_id, role="caretaker")
    caretaker.delete()
    messages.success(request, "Caretaker deleted")
    return redirect("caretaker_list")


# ================= TENANT =================
@login_required
def tenant_create(request):
    if request.user.role not in ["landlord", "caretaker"]:
        return redirect("login")

    if request.method == "POST":
        first_name = request.POST.get("first_name")
        last_name = request.POST.get("last_name")
        id_number = request.POST.get("id_number")
        phone_number = request.POST.get("phone_number")

        username = f"{first_name}{last_name}".lower()

        if User.objects.filter(username=username).exists():
            username = f"{username}{User.objects.count()}"

        if User.objects.filter(phone_number=phone_number).exists():
            messages.error(request, "Phone number already exists")
            return redirect("tenant_add")

        user = User.objects.create(
            username=username,
            first_name=first_name,
            last_name=last_name,
            phone_number=phone_number,
            role="tenant",
            is_first_login=True
        )

        user.set_password(id_number)
        user.save()

        TenantProfile.objects.get_or_create(
            user=user,
            defaults={
                "id_number": id_number,
                "mpesa_number": phone_number,
                "occupants": 1
            }
        )

        messages.success(request, "Tenant created successfully.")
        return redirect("tenant_list")

    return render(request, "accounts/tenant_form.html")


@login_required
def tenant_list(request):
    unit_id = request.GET.get("unit")
    building_id = request.GET.get("building")
    search = request.GET.get("search")

    tenants = User.objects.filter(role="tenant")

    if search:
        tenants = tenants.filter(
            Q(username__icontains=search) |
            Q(first_name__icontains=search) |
            Q(last_name__icontains=search)
        )

    tenant_data = []

    for tenant in tenants:
        profile = TenantProfile.objects.filter(user=tenant).first()

        if building_id and profile and profile.unit:
            if str(profile.unit.building.id) != building_id:
                continue

        latest_payment = Payment.objects.filter(
            tenant=tenant
        ).order_by("-created_at").first()

        rent_status = "Paid" if latest_payment else "Unpaid"

        tenant_data.append({
            "user": tenant,
            "profile": profile,
            "rent_status": rent_status
        })

    buildings = Building.objects.all()

    return render(request, "accounts/tenant_list.html", {
        "tenant_data": tenant_data,
        "unit_id": unit_id,
        "buildings": buildings
    })

@login_required
def profile_view(request):
    user = request.user

    if request.method == "POST":
        user.first_name = request.POST.get("first_name")
        user.last_name = request.POST.get("last_name")
        user.phone_number = request.POST.get("phone_number")
        user.save()

        messages.success(request, "Profile updated successfully")
        return redirect("profile")

    return render(request, "accounts/profile.html", {
        "user": user
    })