from django.http import FileResponse, Http404, HttpResponse, JsonResponse
from django.contrib.auth.decorators import login_required
import os
from django.conf import settings
from django.shortcuts import render, redirect
import base64
from .models import Reservation, Instance, Element, PpsForms, Link
from datetime import datetime, timedelta
from calendar import monthrange
from .forms import ReservationForm 
import calendar
from django.views.decorators.csrf import csrf_exempt

@login_required
def protected_static(request, path):
    file_path = os.path.join(settings.BASE_DIR, 'protected_static/', path)
    if os.path.exists(file_path):
        with open(file_path, 'rb') as file:
            encoded_css = base64.b64encode(file.read()).decode('utf-8')
        return HttpResponse(f'{encoded_css}', content_type='text/html')
    else:
        raise Http404("File not found")

def home_view(request):
    date_today = datetime.now()

    date_today = date_today + timedelta(hours=7)
    year, month, today = date_today.year, date_today.month, date_today.day
    
    # Cari hari pertama bulan ini dan hari terakhir bulan ini
    first_day_of_month = datetime(year, month, 1)
    last_day_of_month = datetime(year, month, monthrange(year, month)[1])
    
    # Cari hari Minggu sebelum hari pertama bulan ini
    start_date = first_day_of_month - timedelta(days=first_day_of_month.weekday() + 1)
    
    # Tentukan tanggal akhir dengan total 35 hari dari start_date
    end_date = start_date + timedelta(days=34)
    
    # Buat daftar tanggal
    date_list = []
    current_date = start_date
    
    while current_date <= end_date:
        status = "inactive" if current_date.month != month else "active"
        class_name = "calendar-table__inactive" if status == "inactive" else "calendar-table__today" if current_date.year == year and current_date.month == month and current_date.day == today else ""
        
        date_list.append({
            "date": current_date.day,
            "month": current_date.month,
            "year": current_date.year,
            "status": status,
            "class": class_name
        })
        
        current_date += timedelta(days=1)

    reservations = Reservation.objects.filter(year=year, month=month)
    approved_reservations = Reservation.objects.filter(status='Approved', year=year, month=month)
    for reservation in approved_reservations:
        for date_item in date_list:
            date = date_item["date"]
            appr_month = date_item["month"]
            appr_year = date_item["year"]
            if reservation.start_date.year == appr_year and reservation.start_date.month == appr_month and reservation.start_date.day == date:
                if reservation.start_date.day == reservation.finish_date.day:
                    date_item["class"] = "calendar-table__event"
                else:
                    date_item["class"] = "calendar-table__event calendar-table__event--long calendar-table__event--start"
            elif reservation.start_date.year == appr_year and reservation.start_date.month == appr_month and reservation.finish_date.day == date:
                date_item["class"] = "calendar-table__event calendar-table__event--long calendar-table__event--end"
            elif reservation.start_date.year == appr_year and reservation.start_date.month == appr_month and reservation.start_date.day < date < reservation.finish_date.day:
                date_item["class"] = "calendar-table__event calendar-table__event--long"
    
    rows = [date_list[i:i+7] for i in range(0, len(date_list), 7)]
    context = {
        "date_list": date_list,
        "monthname": date_today.strftime('%B'),
        "month": month,
        "year": year,
        "rows": rows,
        "reservations": reservations
    }
    # return JsonResponse(date_list, safe=False)
    return render(request, 'base.html', context)

def home_view_filter(request, month=None, year=None):
    date_today = datetime.now()

    date_today = date_today + timedelta(hours=7)
    
    if not year:
        year = date_today.year
    if not month:
        month = date_today.month
    
    year, month = int(year), int(month)

    month_int = month
    month_abbr = calendar.month_name[month_int]
    
    # Cari hari pertama bulan ini dan hari terakhir bulan ini
    first_day_of_month = datetime(year, month, 1)
    last_day_of_month = datetime(year, month, monthrange(year, month)[1])
    
    # Cari hari Minggu sebelum hari pertama bulan ini
    start_date = first_day_of_month - timedelta(days=first_day_of_month.weekday() + 1)
    
    # Tentukan tanggal akhir dengan total 35 hari dari start_date
    end_date = start_date + timedelta(days=34)
    
    # Buat daftar tanggal
    date_list = []
    current_date = start_date
    
    while current_date <= end_date:
        status = "inactive" if current_date.month != month else "active"
        class_name = "calendar-table__inactive" if status == "inactive" else "calendar-table__today" if current_date.year == date_today.year and current_date.month == date_today.month and current_date.day == date_today.day else ""
        
        date_list.append({
            "date": current_date.day,
            "month": current_date.month,
            "year": current_date.year,
            "status": status,
            "class": class_name
        })
        
        current_date += timedelta(days=1)

    reservations = Reservation.objects.filter(year=year, month=month)
    approved_reservations = Reservation.objects.filter(status='Approved', year=year, month=month)
    for reservation in approved_reservations:
        for date_item in date_list:
            date = date_item["date"]
            appr_month = date_item["month"]
            appr_year = date_item["year"]
            if reservation.start_date.year == appr_year and reservation.start_date.month == appr_month and reservation.start_date.day == date:
                if reservation.start_date.day == reservation.finish_date.day:
                    date_item["class"] = "calendar-table__event"
                else:
                    date_item["class"] = "calendar-table__event calendar-table__event--long calendar-table__event--start"
            elif reservation.start_date.year == appr_year and reservation.start_date.month == appr_month and reservation.finish_date.day == date:
                date_item["class"] = "calendar-table__event calendar-table__event--long calendar-table__event--end"
            elif reservation.start_date.year == appr_year and reservation.start_date.month == appr_month and reservation.start_date.day < date < reservation.finish_date.day:
                date_item["class"] = "calendar-table__event calendar-table__event--long"
    
    rows = [date_list[i:i+7] for i in range(0, len(date_list), 7)]
    context = {
        "date_list": date_list,
        "monthname": month_abbr,
        "month": month,
        "year": year,
        "rows": rows,
        "reservations": reservations
    }
    # return JsonResponse(date_list, safe=False)
    return render(request, 'base.html', context)

@csrf_exempt
def add_reservation(request):
    if request.method == "POST":
        try:
            from_date = request.POST.get("from_date")
            to_date = request.POST.get("to_date")
            activity_title = request.POST.get("activity_title")
            jam_mulai = request.POST.get("jam_mulai")
            jam_selesai = request.POST.get("jam_selesai")
            person_count = request.POST.get("person_count")
            responsible_person = request.POST.get("responsible_person")
            phone_number = request.POST.get("phone_number")

            # Ensure required fields are present
            if not all([from_date, to_date, activity_title, jam_mulai, jam_selesai, person_count, responsible_person, phone_number]):
                return JsonResponse({"error": "Missing required fields"}, status=400)

            # Save to database
            add_reservation = Reservation(
                title=activity_title,
                start_date=from_date,
                finish_date=to_date,
                clock_start=jam_mulai,
                clock_end=jam_selesai,
                person_count=person_count,
                responsible_person=responsible_person,
                phone_number=phone_number,
                status="Pending",
                year=datetime.now().year,
                month=datetime.now().month,
            )
            add_reservation.save()

            return JsonResponse({"code": 200, "message": "Reservation saved successfully!"}, status=200)

        except Exception as e:
            return JsonResponse({"code": 500, "error": f"Something went wrong: {str(e)}"}, status=500)

    return JsonResponse({"error": "Invalid request method"}, status=405)

@login_required
def update_reservation_status(request):
    if request.method == "POST":
        try:
            reservation_id = request.POST.get("reservation_id")
            new_status = request.POST.get("status")

            # Check if the reservation exists
            reservation = Reservation.objects.get(id=reservation_id)
            reservation.status = new_status
            reservation.save()

            return JsonResponse({"code": 200, "message": "Status updated successfully!"}, status=200)
        
        except Reservation.DoesNotExist:
            return JsonResponse({"code": 404, "error": "Reservation not found"}, status=404)
        
        except Exception as e:
            return JsonResponse({"code": 500, "error": str(e)}, status=500)

    return JsonResponse({"code": 405, "error": "Invalid request method"}, status=405)

def post_instance(request):
    if request.method == 'POST':
        instance_name = request.POST.get('instance_name')
        responsible_person = request.POST.get('responsible_person')
        phone_number = request.POST.get('phone_number')
        instance_alias = instance_name.lower().replace(' ', '-')

        if instance_name and responsible_person and phone_number:
            instance = Instance(
                instance_name=instance_name,
                responsible_person=responsible_person,
                phone_number=phone_number,
                instance_alias=instance_alias,
            )
            instance.save()
            elements = Element.objects.all()
            
            for element in elements:
                short_code = element.roman_number
                
                original_url = f"https://pps.aklik.id/{instance_alias}/{short_code}"
                
                link = Link(
                    instance=instance,
                    element=element,
                    original_url=original_url,
                    short_code=short_code
                )
                link.save()
            return HttpResponse(f'<h2>Berhasil..!</h2><ul class="noBullet"><li><label for="instance_name"></label><input readonly type="text" class="inputFields" value="{instance_name}"/></li><li><label for="responsible_person"></label><input readonly type="text" class="inputFields" value="{responsible_person}"/></li><li><label for="phone_number"></label><input readonly type="text" class="inputFields" value="{phone_number}" /></li><label for="instance_alias"></label><input readonly type="text" id="instance_alias" class="inputFields" value="https://pps.aklik.id/{instance_alias}" /></li><li id="center-btn" class="left-btn"><button class="tooltip" type="button" style="margin-right: 10px;" onclick="refresh()" id="btn"><span class="tooltiptext">New Links</span><i class="fa fa-refresh"></i></button><button class="tooltip" type="button" onclick="downloadLink()" id="btn"><span class="tooltiptext">Download</span><i class="fa fa-file-download"></i></button></li></ul>', status=201)
        else:
            return HttpResponse('Invalid data', status=400)
    else:
        return HttpResponse('Invalid request method', status=405)

def get_links(request, instance_alias):
    try:
        instance = Instance.objects.get(instance_alias=instance_alias)
        links = Link.objects.filter(instance=instance)
        link_data = [{'url': link.original_url, 'element': link.element.code, 'description': link.element.description} for link in links]
        context = {
            'links': link_data 
        }
        return render(request, 'table_list.html', context)
    except Instance.DoesNotExist:
        return JsonResponse({'error': 'Instance not found'}, status=404)

def get_link_detail(request, instance_alias, short_code):
    try:
        link = Link.objects.get(instance__instance_alias=instance_alias, short_code=short_code)
        if request.method == 'POST':

            # Get or create PpsForms object for this link
            pps_form, created = PpsForms.objects.get_or_create(link=link)
            
            # Update PpsForms fields with POST data
            pps_form.activity = request.POST.get('activity')
            pps_form.improvement_plan = request.POST.get('improvement_plan')
            pps_form.achievement_indicator = request.POST.get('achievement_indicator')
            pps_form.overview = request.POST.get('overview')
            pps_form.completion_time = request.POST.get('completion_time')
            pps_form.funding_source = request.POST.get('funding_source')
            pps_form.responsible_person = request.POST.get('responsible_person')
            
            # Save the updated PpsForms object
            pps_form.save()
            
            # Return a success response
            return redirect(request.path)
        pps_form = PpsForms.objects.filter(link=link).first()
        
        context = {
            'link': link,
            'activity': pps_form.activity if pps_form else None,
            'improvement_plan': pps_form.improvement_plan if pps_form else None,
            'achievement_indicator': pps_form.achievement_indicator if pps_form else None,
            'overview': pps_form.overview if pps_form else None,
            'completion_time': pps_form.completion_time.strftime('%Y-%m-%d') if pps_form else None,
            'funding_source': pps_form.funding_source if pps_form else None,
            'responsible_person': pps_form.responsible_person if pps_form else None,
        }
        
        return render(request, 'link_detail.html', context)
    except Link.DoesNotExist:
        raise Http404("Link not found")

def download_file(request, instance_alias):
    try:
        instance = Instance.objects.get(instance_alias=instance_alias)
        links = Link.objects.filter(instance=instance)
        
        response = HttpResponse(content_type='text/plain')
        response['Content-Disposition'] = f'attachment; filename="{instance_alias}-link.txt"'
        
        for link in links:
            response.write(f"LINK: {link.original_url}\n")
            response.write(f"Element: {link.element.code} {link.element.description}\n\n")
        
        return response
    except Instance.DoesNotExist:
        raise Http404("Instance not found")
