
from django.db.models import Count
from django.urls import reverse
from django.http import HttpResponse,HttpResponseRedirect
from django.core.paginator import Paginator
from django.core.exceptions import PermissionDenied
from django.contrib import messages
from django.contrib.postgres.search import SearchVector
from django.shortcuts import render,redirect
from webapp.auth import urlpath_validate
from webapp.common import dump,log_activity
from webapp.models import (koleksi as m_koleksi, master as m_master)
from . import upload
from . import upload as suratf_upload
from django.db import connection
from .form import ViewForm as SuratForm


def page_list(request,surat_type):
	surat_type = str(surat_type).upper()

	allowed_roles = m_master.Roles.objects.exclude(role__startswith='OPERATOR').values_list('role',flat=1)
	allowed_roles = list(allowed_roles)

	disp = request.GET.get('disp')
	page_show = request.GET.get('item_jml')
	allowed_sorting = ['asc', 'desc']
	sorting_req = request.GET.get('sorting')
	if sorting_req in allowed_sorting:
		request.session['sorting_{}'.format(surat_type)] = sorting_req
	sorting = request.session.get('sorting_{}'.format(surat_type), 'desc')
        


	if disp != None and disp != '':
		display = disp
		if disp == 'list':
			display = 'list'
		elif disp == 'col':
			display = 'col'
		request.session['disp_{}'.format(surat_type)] = display

	if page_show != None and page_show != '' and page_show.isnumeric():
		request.session['page_show_{}'.format(surat_type)] = page_show

	if sorting != None and sorting != '':
		request.session['sorting_{}'.format(surat_type)] = sorting
		sorting = request.session.get('sorting_{}'.format(surat_type), 'desc')

	page_curr = request.GET.get('page')
	page_curr = int(page_curr) if isinstance(page_curr,str) and page_curr.isdigit() == True else 1
	page_curr = 1 if page_curr < 1 else page_curr

	kweri_filter = {}
	page_term = request.GET.get('term','').strip()

	page_term = '' if len(page_term) < 3 else page_term
	if page_term:
		kweri_filter['cari2x__icontains'] = page_term

	if sorting == 'desc':
		kweri = m_koleksi.Surat.objects.annotate(
			banyak_berkas=Count('suratf'),
			cari2x=SearchVector(
				'nomor',
				'perihal',
				'sifat',
				'jenis',
				'pengirim_nama',
				'pengirim_instansi',
				'penerima_nama',
				'penerima_instansi',
			),
		).filter(
			_type=surat_type,
			**kweri_filter
		).order_by('-created')
	else:
		kweri = m_koleksi.Surat.objects.annotate(
			banyak_berkas=Count('suratf'),
			cari2x=SearchVector(
				'nomor',
				'perihal',
				'sifat',
				'jenis',
				'pengirim_nama',
				'pengirim_instansi',
				'penerima_nama',
				'penerima_instansi',
			),
		).filter(
			_type=surat_type,
			**kweri_filter
		).order_by('created')

	paging = Paginator(kweri,6 if request.session.get('page_show_{}'.format(surat_type)) == None else request.session.get('page_show_{}'.format(surat_type)))
	paging = paging.page(page_curr)

	result = []
	for i in paging:
		i = m_koleksi.Surat._sanitize_result(i)
		i['thumbnail'] =  m_koleksi.Suratf._read_many(pk_surat=i['pk'], is_deleted=False)
		i['banyak_berkas'] = len(i['thumbnail'])
		result.append(i)

	return render(request,'surat/list.html', {
		'page_show': page_show,
		'page_curr': page_curr,
		'page_term': page_term,
		'surat_type': surat_type,
		'allowed_roles': allowed_roles,
		'paging': paging,
		'display': 'list' if request.session.get('disp_{}'.format(surat_type)) == None else request.session.get('disp_{}'.format(surat_type)),
		'show' : 6 if request.session.get('page_show_{}'.format(surat_type)) == None else request.session.get('page_show_{}'.format(surat_type)),
		'sorting': 'desc' if request.session.get('sorting_{}'.format(surat_type)) == None else request.session.get('sorting_{}'.format(surat_type)),
		'list': result,
	})
# 

def page_item(request,surat_type,surat_pk):
	surat_type = str(surat_type).upper()

	surat  = m_koleksi.Surat.objects.get(_type=surat_type,pk=surat_pk)
	suratf = m_koleksi.Suratf.objects.filter(pk_surat=surat_pk, is_deleted=False)

	#start agus 28/4/2025
	status_surat = surat.status_surat

	return render(request,'surat/item.html',{
		'surat_type': surat_type,
		'surat' : surat,
		'suratf': suratf,
		'status_surat': status_surat,
	})
	#end
# 
def page_deletef(request, pk):
    surat_file = m_koleksi.Suratf.objects.get(pk=pk)
    surat_file.is_deleted = True
    surat_file.save()
    return HttpResponse(None)


def page_delete(request, _type, pk):
    """
    Hapus surat (hard delete) — lampiran dihapus permanen.
    """
    surat_type = str(_type).upper()
    surat = m_koleksi.Surat.objects.get(_type=surat_type, pk=pk)

    allowed_roles = m_master.Roles.objects.exclude(role__startswith='OPERATOR').values_list('role', flat=1)
    allowed_roles = list(allowed_roles)

    if (request.session['role'] in allowed_roles or surat.user_input == request.session['pk']) == False:
        raise PermissionDenied

    # Hapus lampiran permanen
    lampiran_list = m_koleksi.Suratf.objects.filter(pk_surat=pk)
    for lampiran in lampiran_list:
        from . import upload
        upload.destroy_one_permanent(lampiran.pk)

    # Hapus disposisi
    m_koleksi.Disposisi.objects.filter(pk_surat=pk).delete()

    # Log
    nomor = surat.nomor
    tipe = surat._type
    log_activity(request, 'delete', 'surat', pk, f'Hapus surat {nomor} ({tipe})')

    surat.delete()

    messages.warning(request, 'Berhasil hapus data.')
    referer = request.META.get('HTTP_REFERER', None)
    if referer and '/list' in referer:
        return HttpResponseRedirect(referer)

    return redirect('surat_list', surat_type=_type.lower())




def page_rollback(request, surat_pk, version_id):
    surat = m_koleksi.Surat.objects.get(pk=surat_pk)

    allowed_roles = m_master.Roles.objects.exclude(role__startswith='OPERATOR').values_list('role', flat=True)
    if request.session['role'] not in allowed_roles and surat.user_input != request.session['pk']:
        raise PermissionDenied

    suratf_upload.rollback_surat(surat_pk, version_id, request.session['pk'])

    log_activity(request, 'rollback', 'surat', surat_pk, f'Rollback surat ke versi {version_id}')

    messages.info(request, f'Berhasil rollback surat ke versi {version_id}.')
    return redirect('surat_item', surat_type=surat._type.lower(), surat_pk=surat_pk)



def page_history(request, surat_pk):
    surat = m_koleksi.Surat.objects.get(pk=surat_pk)

    with connection.cursor() as cursor:
        cursor.execute("""
            SELECT sv.*, u.usr AS user_nama
            FROM surat_versions sv
            LEFT JOIN users u ON u.pk = sv.user_input
            WHERE sv.pk_surat = %s
            ORDER BY sv.created DESC
        """, [surat_pk])

        columns = [col[0] for col in cursor.description]
        versions = [dict(zip(columns, row)) for row in cursor.fetchall()]

    for v in versions:
        v['attachments'] = m_koleksi.SuratVersionAttachment.objects.filter(pk_version=v['pk'])
    surat_type = surat._type
    return render(request, 'surat/history.html', {
    'surat': surat,
    'versions': versions,
    'surat_type': surat_type,
    })

def page_create(request, surat_type):
    surat_type = surat_type.upper()
    form = SuratForm(request.POST or None)

    if request.method == 'POST' and form.is_valid():
        surat = form.save(commit=False)
        surat._type = surat_type
        surat.user_input = request.session['pk']
        surat.save()

        # Upload lampiran baru
        upload.deploy(request, surat.pk, request.FILES.getlist('suratf'))

        # Simpan versi pertama
        upload.save_surat_version(surat, request.session['pk'])

        log_activity(request, 'create', 'surat', surat.pk, f'Buat surat {surat.nomor}')
        messages.success(request, 'Surat berhasil dibuat.')
        return redirect('surat_item', surat_type=surat_type.lower(), surat_pk=surat.pk)

    return render(request, 'surat/form.html', {
        'form': form,
        'surat_type': surat_type,
        'berkas': [],
    })

def page_update(request, surat_type, surat_pk):
    surat_type = surat_type.upper()
    surat = m_koleksi.Surat.objects.get(_type=surat_type, pk=surat_pk)
    form = SuratForm(request.POST or None, instance=surat)

    if request.method == 'POST' and form.is_valid():
        # Soft delete lampiran yang ditandai
        pending_ids = request.POST.get('pending_delete_ids', '')
        if pending_ids:
            ids = [int(x) for x in pending_ids.split(',') if x.isdigit()]
            m_koleksi.Suratf.objects.filter(pk__in=ids).update(is_deleted=True)

        # Save versi aktif sebelum update
        upload.save_surat_version(surat, request.session['pk'])

        # Update surat metadata
        surat = form.save()

        # Upload lampiran baru
        upload.deploy(request, surat.pk, request.FILES.getlist('suratf'))

        log_activity(request, 'edit', 'surat', surat.pk, f'Edit surat {surat.nomor}')
        messages.success(request, 'Surat berhasil diperbarui.')
        return redirect('surat_item', surat_type=surat_type.lower(), surat_pk=surat.pk)

    # Ambil lampiran aktif
    berkas = m_koleksi.Suratf.objects.filter(pk_surat=surat.pk, is_deleted=False)

    return render(request, 'surat/form.html', {
        'form': form,
        'surat_type': surat_type,
        'surat_pk': surat_pk,
        'berkas': berkas,
    })

