# -*- coding: utf-8 -*-
from django.shortcuts import render
from django.db.models import Sum, Count, OuterRef,Subquery
from django.http import JsonResponse


from datetime import timedelta, datetime
import json

from management.models import StorageFacility
from stock.models import Receipt, ReceiptItem, WriteOff, Stock, Reservation, InvoiceWritingOffMaterial, WritingOffMaterialsItem, InvoiceMovementMaterial, MovementMaterialsItem
from management.models import Good
from custom_user.models import User


# Create your views here.

def report(request):
    return render(request, 'report/report.html')

def report_receipt(request):
    try:
        if request.method == 'GET':
            return render(request, 'report/report_receipt.html')
        elif request.method == 'POST':
            data = json.loads(request.body)
            # date_start = datetime.strptime(data['data'].get("date_start"), "%Y-%m-%d")
            date_start = datetime.strptime(data['data'].get("date_start"), "%d-%m-%Y")
            date_end = datetime.strptime(data['data'].get("date_end"), "%d-%m-%Y")
            date_end_for_search = (date_end + timedelta(days=1))

            receipts = []
            _receipts = Receipt.objects.filter(date__range=[date_start, date_end_for_search]).values('id','vendor', 'invoice', 'date', 'storage_facility__name', 'created_by')
            for item in _receipts:
                data = {}
                data['id'] = item['id']
                data['vendor'] = item['vendor']
                data['invoice'] = item['invoice']
                data['date'] = item['date']
                data['storage_facility__name'] = item['storage_facility__name']
                user = User.objects.get(email = item.get('created_by'))
                data['user_first_name'] = user.first_name
                data['user_last_name'] = user.last_name
                receipts.append(data)

            return JsonResponse({'message': 'Success', 'data': receipts}, safe=False)
    except Exception as error:
        raise error

def receipt_detail(request, id):
    receipt = Receipt.objects.get(id=id)
    receipt_items = ReceiptItem.objects.filter(receipt=receipt.id)
    # Товар	Кількість	Одиниці	Ціна
    total_price = 0.0
    for item in receipt_items:
        sum_value = float(item.quantity) * float(item.price)
        total_price += sum_value
    return render(request, 'report/receipt_detail.html', context={"receipt":receipt, "receipt_items":receipt_items, "total_price":total_price})

def report_write_off(request):
    try:
        if request.method == 'GET':
            return render(request, 'report/report_write_off.html')
        elif request.method == 'POST':
            data = json.loads(request.body)
            date_start = datetime.strptime(data['data'].get("date_start"), "%d-%m-%Y")
            date_end = datetime.strptime(data['data'].get("date_end"), "%d-%m-%Y")
            date_end_for_search = (date_end + timedelta(days=1))

            invoices_write_off = []
            _invoices_write_off = InvoiceWritingOffMaterial.objects.filter(created_at__range=[date_start, date_end_for_search]).values(
                'id',
                'invoice', 
                'reason', 
                'date', 
                'created_by', 
                'project_id__name'
                )

            for item in _invoices_write_off:
                data = {}
                data['id'] = item['id']
                data['invoice'] = item['invoice']
                data['reason'] = item['reason']
                data['date'] = item['date']
                user = User.objects.get(email = item.get('created_by'))
                data['user_first_name'] = user.first_name
                data['user_last_name'] = user.last_name
                data['project_name'] = item['project_id__name']
                invoices_write_off.append(data)
            return JsonResponse({'message': 'Success', 'data': invoices_write_off}, safe=False)
            # return render(request, 'report/report_write_off.html', context={"invoices_write_off":invoices_write_off, "date_start":date_start, "date_end":date_end})
    except Exception as error:
        raise error

def write_off_detail(request, id):
    try:
        invoice = InvoiceWritingOffMaterial.objects.get(id=id)
        invoice_items = WritingOffMaterialsItem.objects.filter(invoice=invoice.id)
        total_price = 0.0
        for item in invoice_items:
            sum_value = float(item.quantity) * float(item.price)
            total_price += sum_value
        return render(request, 'report/write_off_detail.html', context={"invoice":invoice, "invoice_items":invoice_items, "total_price":total_price})

    except Exception as error:
        raise error

def all_goods_in_stock(request):
    try:
        if request.method == 'GET':
            stock_sum = 0.00
            tmc_with_quantity = Stock.objects.filter(actual_quantity__gt=0).values('good_id__name','good_id__unit_of_measurement', 'price', 'storage_facility_id__name').annotate(
                total_quantity=Sum('actual_quantity'),
            ).order_by('good_id__name')


            for tmc in tmc_with_quantity:
                tmc['total_sum'] = tmc['total_quantity'] * tmc['price']
                stock_sum += tmc['total_sum']

            return render(request, 'report/all_tmc_in_stock.html', context={"tmc_with_quantity":tmc_with_quantity, "stock_sum":stock_sum})
    except Exception as error:
        raise error

def reservation_report_list(request):
    try:
        # unique_project_ids = Reservation.objects.filter(project_id=OuterRef('project_id')).order_by('-id').values('id')[:1]
        # objects = Reservation.objects.filter(id__in=Subquery(unique_project_ids)).values('project_id', 'project_id__name', 'date', 'created_by')
        unique_project_ids = Reservation.objects.all().distinct().values('project_id', 'project_id__name', 'date', 'created_by')
        # objects = Reservation.objects.filter(id__in=Subquery(unique_project_ids)).values('project_id', 'project_id__name', 'date', 'created_by')
        for item in unique_project_ids:
                user = User.objects.get(email = item['created_by'])  or 'System'
                item['user'] = user
        return render(request, 'report/reservation.html', {"objects":unique_project_ids})
    except Exception as error:
        raise error

def reservation_report_detail(request,id):
    try:
        reservation_items = Reservation.objects.filter(project=id).values('good_id__name', 'quantity', 'date', 'created_by')
        for item in reservation_items:
            user = User.objects.get(email = item['created_by'])  or 'System'
            item['user'] = user
        return render(request, 'report/resrvation_detail.html', {"reservation_items":reservation_items})
    except Exception as error:
        raise error

def report_by_good_name(request):
    try:
        if request.method == 'GET':
            goods = Good.objects.all().values("name")
            return render(request, 'report/report_one_good.html', {"goods":goods})
        elif request.method == 'POST':
            data = json.loads(request.body)
            
            date_start = datetime.strptime(data['data'].get("date_start"), "%d-%m-%Y")
            date_end = datetime.strptime(data['data'].get("date_end"), "%d-%m-%Y")
            good_name = data['data'].get("good_name")
            unit_of_measurement = data['data'].get("unitsOfMeasurement")
            if not good_name:
                return JsonResponse({'message': 'Error', 'data': str('Введіть корректні данні') })

            good_photo = None
            good = Good.objects.get(name = good_name, unit_of_measurement=unit_of_measurement)
            if good.photo:
                good_photo = good.photo.url

            date_end_for_search = (date_end + timedelta(days=1))

            total_actual_quantity = Stock.objects.filter(good_id=good.id).aggregate(Sum('actual_quantity'))['actual_quantity__sum']  or 0
            total_reservation = Reservation.objects.filter(good_id=good.id).aggregate(Sum('quantity'))['quantity__sum']  or 0
            balance = total_actual_quantity - total_reservation

            # receipt = ReceiptItem.objects.filter(good_id=good.id, created_at__range=[date_start, date_end_for_search]).order_by('-created_at')

            reservation_items = []
            # Кіл-сть	Дата	Користувач	Обьєкт
            _reservation_items = Reservation.objects.filter(good_id=good.id, date__range=[date_start, date_end_for_search]).order_by('-date').values(
                'quantity',
                'date',
                'project__name',
                'created_by'
            )
            for item in _reservation_items:
                data = {}
                original_date = datetime.fromisoformat(str(item['date']))
                formatted_date = original_date.strftime("%d.%m.%Y")
                data['quantity'] = item['quantity']
                data['date'] = formatted_date
                data['project_name'] = item['project__name']
                user = User.objects.get(email = item.get('created_by'))
                data['user_first_name'] = user.first_name
                data['user_last_name'] = user.last_name
                reservation_items.append(data)

            write_off_items = []
            _write_off_items =  WritingOffMaterialsItem.objects.filter(good_id=good.id, created_at__range=[date_start, date_end_for_search]).order_by('-created_at').values(
                'invoice',
                'quantity',
                'created_at',
                'price',
            )
            for item in _write_off_items:
                data = {}
                original_date = datetime.fromisoformat(str(item['created_at']))
                formatted_date = original_date.strftime("%d.%m.%Y")
                data['invoice_id'] = item['invoice']
                data['quantity'] = item['quantity']
                data['created_at'] = formatted_date
                invoice = InvoiceWritingOffMaterial.objects.get(id =item['invoice'])
                user = User.objects.get(email = invoice.created_by)
                data['user_first_name'] = user.first_name
                data['user_last_name'] = user.last_name
                data['reason'] = invoice.reason
                data['total_sum'] = float(item['quantity']) * float(item['price'])
                data['invoice_number'] = invoice.invoice
                write_off_items.append(data)

            receipts_items = []
            _receipts_items = ReceiptItem.objects.filter(good_id=good.id, date__range=[date_start, date_end_for_search]).order_by('-date').values('id','quantity', 'price','created_by', 'receipt', 'date', 'receipt_id__storage_facility__name')
            for item in _receipts_items:
                data = {}
                data['id'] = item['id']
                data['quantity'] = item['quantity']
                data['price'] = item['price']
                data['created_at'] = item['date']
                user = User.objects.get(email = item.get('created_by'))
                data['user_first_name'] = user.first_name
                data['user_last_name'] = user.last_name
                data['actual_quantity'] = Stock.objects.filter(good_id=good.id, receipt = item['receipt']).aggregate(Sum('actual_quantity'))['actual_quantity__sum']  or 0
                data['storage'] = item['receipt_id__storage_facility__name']
                receipts_items.append(data)


            return JsonResponse({
                'message': 'Success',
                'total_actual_quantity':total_actual_quantity, 
                'balance':balance,
                'total_reservation':total_reservation,
                'receipts_items':receipts_items,
                'write_off_items':write_off_items,
                'reservation_items':reservation_items,
                'good_photo':good_photo,
                }, safe=False)
    except Exception as error:
        raise error


def report_movement_beatween_stocks(request):
    try:
        if request.method == 'GET':
            return render(request, 'report/report_movement_beatween_stocks.html')
        elif request.method == 'POST':
            data = json.loads(request.body)
            date_start = datetime.strptime(data['data'].get("date_start"), "%d-%m-%Y")
            date_end = datetime.strptime(data['data'].get("date_end"), "%d-%m-%Y")
            date_end_for_search = (date_end + timedelta(days=1))

            movement = []
            _movement = InvoiceMovementMaterial.objects.filter(created_at__range=[date_start, date_end_for_search]).values('id','invoice', 'storage_from', 'storage_to', 'created_at', 'created_by')
            for item in _movement:
                data = {}
                data['id'] = item['id']
                data['invoice'] = item['invoice']
                data['storage_from'] = StorageFacility.objects.get(id = item.get('storage_from')).name
                data['storage_to'] = StorageFacility.objects.get(id = item.get('storage_to')).name
                data['date'] = item['created_at']
                user = User.objects.get(email = item.get('created_by'))
                data['user_first_name'] = user.first_name
                data['user_last_name'] = user.last_name
                movement.append(data)

            return JsonResponse({'message': 'Success', 'data': movement}, safe=False)
    except Exception as error:
        raise error

def report_movement_beatween_stocks_detail(request, id):
    try:
        invoice = InvoiceMovementMaterial.objects.get(id=id)
        invoice_items = MovementMaterialsItem.objects.filter(invoice=invoice.id)
        total_price = 0.0
        for item in invoice_items:
            sum_value = float(item.quantity) * float(item.price)
            total_price += sum_value
        return render(request, 'report/write_off_detail.html', context={"invoice":invoice, "invoice_items":invoice_items, "total_price":total_price})

    except Exception as error:
        raise error