import hashlib
from pathlib import Path
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
from django.db import transaction
from django.http import FileResponse,Http404
from django.shortcuts import get_object_or_404,redirect,render
from django.views.decorators.http import require_POST
from .forms import UploadForm
from .models import ActivityLog,ClientProfile,TaxCase,TaxDocument

def event(request,action,case=None,document=None):
 ActivityLog.objects.create(actor=request.user,action=action,case=case,document=document,ip=request.META.get('REMOTE_ADDR'))
def is_staff(user): return user.is_active and user.is_staff
@login_required
def dashboard(request):
 if is_staff(request.user):
  cases=TaxCase.objects.select_related('client__user').order_by('-updated_at')[:100]
  return render(request,'portal/dashboard.html',{'cases':cases,'staff_dashboard':True,'pending_count':TaxDocument.objects.filter(scan_status='pending').count()})
 profile=get_object_or_404(ClientProfile,user=request.user)
 cases=TaxCase.objects.filter(client=profile).order_by('-year')
 return render(request,'portal/dashboard.html',{'cases':cases,'staff_dashboard':False})
@login_required
def case_detail(request,case_id):
 case=get_object_or_404(TaxCase.objects.select_related('client__user'),pk=case_id)
 if not is_staff(request.user) and case.client.user_id!=request.user.id: raise PermissionDenied
 documents=case.documents.order_by('-uploaded_at')
 return render(request,'portal/case.html',{'case':case,'documents':documents,'form':UploadForm(),'can_upload':not is_staff(request.user)})
@login_required
@require_POST
def upload(request,case_id):
 case=get_object_or_404(TaxCase,pk=case_id)
 if is_staff(request.user) or case.client.user_id!=request.user.id: raise PermissionDenied
 form=UploadForm(request.POST,request.FILES)
 if form.is_valid():
  f=form.cleaned_data['file']; digest=hashlib.sha256()
  for chunk in f.chunks(): digest.update(chunk)
  f.seek(0)
  doc=form.save(commit=False)
  doc.case=case;doc.client=case.client;doc.original_filename=Path(f.name).name[:255];doc.size=f.size;doc.sha256=digest.hexdigest()
  doc.save();event(request,'document_uploaded',case,doc)
  messages.success(request,'PDF received and quarantined for security scanning. It will not be downloadable until cleared.')
 else:
  for errors in form.errors.values():
   for error in errors: messages.error(request,error)
 return redirect('case',case_id=case.id)
@login_required
def download(request,document_id):
 doc=get_object_or_404(TaxDocument.objects.select_related('client__user','case'),pk=document_id)
 if not is_staff(request.user) and doc.client.user_id!=request.user.id: raise PermissionDenied
 if doc.scan_status!='clean': raise Http404('Document is not available until security review is complete.')
 try: opened=doc.file.open('rb')
 except (FileNotFoundError,OSError): raise Http404
 event(request,'document_downloaded',doc.case,doc)
 response=FileResponse(opened,as_attachment=True,filename=doc.original_filename,content_type='application/pdf')
 response['Cache-Control']='private, no-store';response['X-Content-Type-Options']='nosniff'
 return response
