from datetime import datetime, timedelta
import json

from django.shortcuts import render, redirect, resolve_url, reverse
from django.contrib import messages
from django.contrib.auth import authenticate, login, logout, update_session_auth_hash
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import Group
from django.contrib.auth.views import LoginView, LogoutView
from django.contrib.auth.forms import PasswordChangeForm, AuthenticationForm
from django.http import HttpResponse, HttpResponseRedirect
from django.views.generic import CreateView, DetailView
from django.contrib.auth.mixins import LoginRequiredMixin

from .forms import SignupForm, LoginForm, UpdateDefaultProfile, UpdateCustomProfile
from .decorators import unauthenticated_user, allowed_users, admin_only
from registers.filters import CustomerFilter

from customers.models import Customer
from orders.models import Order
from products.models import Product, HistConf
from registers.models import Profile


# --------------- Dashboard & Home --------------- #
@login_required(login_url='/user/login/')
def dashboard(request):
    customers = Customer.objects.all()
    total_customers = customers.count()

    orders = Order.objects.all()
    total_orders = orders.count()

    products = Product.objects.all()
    total_products = products.count()

    pending = orders.filter(status='Pending').count()
    delivered = orders.filter(status='Delivered').count()

    # filtering customers (if any GET params)
    myFilter = CustomerFilter(request.GET, queryset=customers)
    customers = myFilter.qs

    # last 24 hours
    today_customers = customers.filter(date_created__gte=datetime.now() - timedelta(days=1)).count()
    today_order = orders.filter(created_at__gte=datetime.now() - timedelta(days=1))

    order_total_price = 0.0
    for order in today_order:
        try:
            per_total_price = float(order.product.price) * order.quantity
        except Exception:
            per_total_price = 0.0
        order_total_price += per_total_price

    context = {
        'customers': customers,
        'orders_total_price': order_total_price,
        'total_orders': total_orders,
        'myFilter': myFilter,
        'today_customers': today_customers,
        'current_data': datetime.now(),
        'orders_pending': pending,
        'orders_delivered': delivered,
        'total_products': total_products,
        'total_customers': total_customers,
    }
    return render(request, 'registers/index.html', context)


def first_page(request):
    current_date = datetime.now()
    return render(request, 'registers/firstpage.html', {'current_date': current_date})


# --------------- Authentication: Login / Signup / Logout --------------- #
@unauthenticated_user
def loginPage(request):
    # Use custom LoginForm if you want extra fields; else AuthenticationForm works
    # Use the AuthenticationForm to benefit from built-in validation
    form = LoginForm(request=request) if hasattr(LoginForm, '__call__') else LoginForm()
    # If LoginForm is a subclass of AuthenticationForm it accepts (request, data)
    if request.method == 'POST':
        # Prefer binding request to AuthenticationForm so Django handles authentication
        try:
            bound_form = LoginForm(request=request, data=request.POST)
        except TypeError:
            # fallback if custom LoginForm signature is different
            bound_form = LoginForm(data=request.POST)

        if bound_form.is_valid():
            # If LoginForm is AuthenticationForm, clean_data has 'username'
            user = bound_form.get_user() if hasattr(bound_form, 'get_user') else None

            if user is None:
                # fallback manual authenticate using username + password
                username = bound_form.cleaned_data.get('username') or request.POST.get('username')
                password = bound_form.cleaned_data.get('password') or request.POST.get('password')
                user = authenticate(request, username=username, password=password)

            if user is not None:
                login(request, user)
                # redirect where the user intended to go, or to dashboard/home
                next_url = request.GET.get('next') or request.POST.get('next') or reverse('dashboard')
                return redirect(next_url)
        else:
            messages.error(request, 'Username OR password is incorrect')
            form = bound_form
    context = {'form': form}
    return render(request, 'registers/login.html', context)


@unauthenticated_user
def SignupView(request):
    form = SignupForm()
    if request.method == 'POST':
        form = SignupForm(request.POST)
        if form.is_valid():
            user = form.save()
            username = form.cleaned_data.get('username')

            # try to add to 'employee' group, create if doesn't exist
            group_name = 'employee'
            group, created = Group.objects.get_or_create(name=group_name)
            user.groups.add(group)

            messages.success(request, f'Account was created for {username}')
            return redirect('register_app:login')
    context = {'form': form}
    return render(request, 'registers/register.html', context)


class UserLogoutView(LogoutView):
    """
    Use this class-based view if you want to hook into LogoutView.
    In urls.py you can map it as:
      path('user/logout/', UserLogoutView.as_view(next_page='/user/login/'), name='logout')
    But using Django's built-in LogoutView directly is fine too.
    """
    pass


# --------------- User Profile & Password Change --------------- #
@login_required(login_url='/user/login/')
def UserProfile(request):
    # Instances loaded for the current user
    defaultForm = UpdateDefaultProfile(instance=request.user)
    customForm = UpdateCustomProfile(instance=getattr(request.user, 'profile', None))
    PassForm = PasswordChangeForm(request.user)

    if request.method == 'POST' and 'profile_edit' in request.POST:
        defaultForm = UpdateDefaultProfile(request.POST, instance=request.user)
        customForm = UpdateCustomProfile(request.POST, request.FILES, instance=getattr(request.user, 'profile', None))

        if defaultForm.is_valid() and customForm.is_valid():
            defaultForm.save()
            customForm.save()
            messages.success(request, "Your record is successfully updated")
            return redirect('register_app:user_view')

    if request.method == 'POST' and 'change_pass_button' in request.POST:
        PassForm = PasswordChangeForm(user=request.user, data=request.POST)
        if PassForm.is_valid():
            PassForm.save()
            update_session_auth_hash(request, PassForm.user)
            messages.success(request, "Your password is successfully updated")
            return redirect('register_app:user_view')
        else:
            messages.error(request, "Please correct the errors in the form.")

    return render(request, 'registers/edit_user.html', {
        'defaultForm': defaultForm,
        'customForm': customForm,
        'PassForm': PassForm
    })
