import json

import nepali_datetime
from django.contrib.auth import login, logout
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.decorators.http import require_POST

from .forms import EmailOrUsernameAuthForm
from .models import IrrigationInquiry, SurveyEditLog, SurveySubmission


def _visible_submissions(user):
    qs = SurveySubmission.objects.all()
    if not user.is_superuser:
        qs = qs.filter(user=user)
    return qs


def login_view(request):
    if request.user.is_authenticated:
        return redirect("home")
    if request.method == "POST":
        form = EmailOrUsernameAuthForm(request, data=request.POST)
        if form.is_valid():
            login(request, form.get_user())
            next_url = request.POST.get("next") or request.GET.get("next") or "/"
            return redirect(next_url)
    else:
        form = EmailOrUsernameAuthForm(request)
    return render(request, "login.html", {"form": form, "next": request.GET.get("next", "")})


def logout_view(request):
    logout(request)
    return redirect("login")


@ensure_csrf_cookie
@login_required
def home(request):
    bs_today = nepali_datetime.date.today()
    bs_months_en = [
        "Baisakh", "Jestha", "Ashadh", "Shrawan", "Bhadra", "Ashwin",
        "Kartik", "Mangsir", "Poush", "Magh", "Falgun", "Chaitra",
    ]

    context = {
        "success_message": "",
        "error_message": "",
        "submitted_data": {},
        "nepali_today": f"{bs_today.day} {bs_months_en[bs_today.month - 1]}, {bs_today.year}",
        "submissions": _visible_submissions(request.user).order_by("-created_at"),
    }

    if request.method == "POST":
        full_name = request.POST.get("full_name", "").strip()
        email = request.POST.get("email", "").strip()
        phone = request.POST.get("phone", "").strip()
        location = request.POST.get("location", "").strip()
        message = request.POST.get("message", "").strip()

        context["submitted_data"] = {
            "full_name": full_name, "email": email,
            "phone": phone, "location": location, "message": message,
        }

        if not full_name or not email or not location or not message:
            context["error_message"] = "Please fill in all required fields."
        else:
            IrrigationInquiry.objects.create(
                full_name=full_name, email=email,
                phone=phone, location=location, message=message,
                user=request.user,
            )
            context["success_message"] = "Your request has been submitted successfully."
            context["submitted_data"] = {}

    return render(request, "index.html", context)


@require_POST
@login_required
def submit_survey(request):
    try:
        payload = json.loads(request.body.decode("utf-8") or "{}")
    except json.JSONDecodeError:
        return JsonResponse({"ok": False, "error": "Invalid JSON payload."}, status=400)

    respondent_name = str(payload.get("informantName", "")).strip()
    mobile = str(payload.get("mobile", "")).strip()
    district = str(payload.get("district", "")).strip()

    SurveySubmission.objects.create(
        respondent_name=respondent_name,
        mobile=mobile,
        district=district,
        payload=payload,
        user=request.user,
    )
    return JsonResponse({"ok": True})


@login_required
def submissions_list(request):
    rows = []
    for sub in _visible_submissions(request.user).order_by("-created_at"):
        p = sub.payload
        system = p.get("irrigation-system", "") or ""
        if system == "other":
            system = p.get("other-system-name", "") or "Other"
        rows.append({
            "id": sub.id,
            "date": p.get("nepali-date", "") or "—",
            "system": system or "—",
            "district": sub.district or p.get("district", "") or "—",
            "municipality": p.get("municipality", "") or "—",
            "ward": p.get("ward", "") or "—",
            "village": p.get("village", "") or "—",
            "fgd": p.get("fgd", "") or "—",
            "created_at": sub.created_at,
            "edit_count": sub.edit_logs.count(),
            "owner": sub.user.username if sub.user_id else "—",
        })
    return render(request, "submissions_list.html", {
        "rows": rows,
        "is_superadmin": request.user.is_superuser,
    })


@login_required
def submission_detail(request, pk):
    submission = get_object_or_404(_visible_submissions(request.user), pk=pk)
    edit_logs = submission.edit_logs.order_by("-edited_at")
    return render(request, "submission_detail.html", {
        "submission": submission,
        "edit_logs": edit_logs,
    })


@require_POST
@login_required
def edit_submission_field(request, pk):
    submission = get_object_or_404(_visible_submissions(request.user), pk=pk)
    try:
        data = json.loads(request.body.decode("utf-8") or "{}")
    except json.JSONDecodeError:
        return JsonResponse({"ok": False, "error": "Invalid JSON"}, status=400)

    field_key = str(data.get("field_key", "")).strip()
    new_value = data.get("new_value")
    field_label = str(data.get("field_label", "")).strip()

    if not field_key:
        return JsonResponse({"ok": False, "error": "field_key required"}, status=400)

    old_value = submission.payload.get(field_key)
    payload_before = dict(submission.payload)

    SurveyEditLog.objects.create(
        submission=submission,
        field_key=field_key,
        field_label=field_label,
        old_value=old_value,
        new_value=new_value,
        payload_before=payload_before,
    )

    submission.payload[field_key] = new_value
    if field_key in ("informant-name", "informantName"):
        submission.respondent_name = str(new_value or "")
    elif field_key == "mobile":
        submission.mobile = str(new_value or "")
    elif field_key == "district":
        submission.district = str(new_value or "")
    submission.save()

    return JsonResponse({"ok": True, "new_value": new_value})
