# Create your views here.

from django.contrib.auth.decorators import login_required
from django.http import FileResponse, HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render

import os
from blake3 import blake3

from .forms import UploadFileForm
from .models import  User_Banner_Images, User_Profile_Images, Metadata_Files, Submission_File


MODEL_MAP = {
   'user_profile': User_Profile_Images,
   'user_banner': User_Banner_Images,
   'submission': Submission_File,
   'metadata': Metadata_Files,
}

def compute_file_hash(file):
    '''
    Compute BLAKE3 hash of the file
    '''
    try:
        hasher = blake3()
        for chunk in file.chunks(chunk_size=65536):
            hasher.update(chunk)
        return hasher.hexdigest()
    except Exception as e:
        print(f"Error computing file hash: {e}")
        return None


@login_required(login_url="/login/")
def serve_content_file(request, folder, file_hash):
   '''
   View function to serve content files for download or inline viewing
   '''
   
   ModelClass = MODEL_MAP.get(folder)
   if ModelClass is None:
       return HttpResponse("Invalid folder", status=404)

   download = request.GET.get('d')

   try:
       obj_file = get_object_or_404(ModelClass, file_hash=file_hash)
       file = obj_file.file.file
       file_name = obj_file.file_name

       response = FileResponse(file)
       if download == "1":
           response['Content-Disposition'] = f'attachment; filename="{file_name}"'
       else:
           response['Content-Disposition'] = f'inline; filename="{file_name}"'

       return response

   except Exception as e:
       print(f"Error serving file: {e}")
       return HttpResponse("File not found", status=404)


@login_required(login_url="/login/")
def fileUpload(request):
    '''
    View function for handling file uploads
    '''
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            if 'file' in request.FILES:  # Check if a file has been uploaded
                file = form.cleaned_data['file']

                file_name = file.name
                file_hash = compute_file_hash(file)

                Null, file_ext = os.path.splitext(file_name)
                hash_file_name = file_hash + file_ext

                new_submission_file, created = Submission_File.objects.get_or_create(file_hash=file_hash)

                new_submission_file.file_hash = file_hash
                new_submission_file.file_name = file_name
                new_submission_file.file.save(hash_file_name, file) 

                new_submission_file.save

                return HttpResponseRedirect(f"/files/submission/{file_hash}")

            else:
                # No file was uploaded, add an error message to the context
                error_message = 'No file was uploaded.'
                return render(request, 'files/upload.html', {'form': form, 'error_message': error_message})

        else:
            # Form is not valid, add an error message to the context
            error_message = 'There was an error with the form.'
            return render(request, 'files/upload.html', {'form': form, 'error_message': error_message})

    else:
        form = UploadFileForm()
        
    return render(request, 'files/upload.html', {'form': form})
