# -*- coding: utf-8 -*-
from django.shortcuts import render
from django.http import JsonResponse
from django.db.models import Sum, F
from django.db import transaction 

from management.models import Good, StorageFacility
from .models import OwnProduction, OwnProductionItem
from stock.models import Stock, Reservation, WriteOff


from utils.utils import remove_spaces_from_string


import json
import pandas as pd 
# Create your views here.

def process_own_product_items(own_product_id, own_product_items):
    try:
        own_product_item_delate = OwnProductionItem.objects.filter(own_production = own_product_id)
        for item in own_product_item_delate:
            item.delete()
        for _, row in own_product_items.iterrows():
            good_name = row['Найменування']
            quantity = float(row['Кількість'])
            own_product_item = OwnProductionItem.objects.update_or_create(
                                            own_production = OwnProduction.objects.get(id = own_product_id),
                                            good = Good.objects.get(name=good_name),
                                            quantity = quantity,
            )
    except Exception as error:
        raise error

def own_production(request):
    goods = Good.objects.all().values('name')
    own_products = OwnProduction.objects.all().values('name')
    storages = StorageFacility.objects.all().values('name')
    return render(request, 'own_production/own_production.html', context={"goods":goods, "own_products":own_products, "storages":storages})

def add_good_by_name(request, name, unit_of_measurement):

    try:
        if Good.objects.filter(name=name, unit_of_measurement=unit_of_measurement).exists():
            return 
        good = Good.objects.create(
                    name = remove_spaces_from_string(name),
                    unit_of_measurement = unit_of_measurement,
                    created_by = request.user,
                )
    except Exception as error:

        raise error

def add_new_own_product(request):

    try:
        if request.method == 'POST':
            name  = request.POST.get("name")
            items = request.POST.get("items")
            unit_of_measurement = request.POST.get("unit_of_measurement")
            _items = pd.read_html(items)[0]

            own_product = OwnProduction.objects.create(
                name = name,
                created_by = request.user
            )
            add_good_by_name(request, name, unit_of_measurement)
            process_own_product_items(own_product.id , _items)

            return JsonResponse({'message': 'Success'})
    except Exception as error:
        return JsonResponse({'status': 'error', 'data': str(error)}, status=500)
    

def get_price_for_good(id, quantity):
    stock_entries = Stock.objects.filter(good_id=id).order_by('date')
    remaining_quantity = quantity
    total_price = 0.0
    for stock_entry in stock_entries:
            if remaining_quantity <= 0:
                break
            
            if stock_entry.quantity >= remaining_quantity:
                # Якщо наявна достатня кількість
                total_price += remaining_quantity * stock_entry.price
                remaining_quantity = 0
            else:
                # Якщо наявна кількість менша, ніж потрібно
                total_price += stock_entry.quantity * stock_entry.price
                remaining_quantity -= stock_entry.quantity  
    return total_price

def check_good_shortage_quantity(good):
    try:

        reservation = Reservation.objects.filter(good=good).aggregate(Sum('quantity'))['quantity__sum']  or 0
        actual_quantity = Stock.objects.filter(good_id=good).aggregate(Sum('quantity'))['quantity__sum'] or 0
        actual_quantity = actual_quantity - reservation

        return actual_quantity

    except Exception as error:

        raise error
    
def add_own_product_to_stock(good, quantity, price, storage):
    try:

        item = Stock.objects.create(
            good_id = good,
            quantity = quantity,
            price = price,
            storage_facility_id = StorageFacility.objects.get(name = storage)
        )


    except Exception as error:

        raise error

def write_off_tmc_from_stock(good, quantity):
    try:

        good = Good.objects.get(name = good).id
        items = Stock.objects.filter(good_id=good).order_by('date')
        total_quantity = sum(item.quantity for item in items)
        if total_quantity < quantity:
            return f"Недосататьня кількість {good} для списання"
        
        for item in items:
            if item.quantity >= quantity:
                item.quantity = F('quantity') - quantity
                item.save()
                break 
            else:
                quantity -= item.quantity
                item.quantity = F('quantity') - item.quantity
                item.save()
    except Exception as error:

        raise error
    

def add_record_in_write_off(request, good_name, quantity, reason):
    #  with transaction.atomic():    
    item = WriteOff.objects.create(
        reason = reason,
        good = Good.objects.get(name=good_name),
        quantity=quantity,
        created_by = request.user
    )


def calculate_cost_own_product(request):
    try:
        if request.method == 'POST':
            name  = request.POST.get("own_product_name")
            quantity = int(request.POST.get("own_product_quantity"))
            storage = request.POST.get("storage")

            product = OwnProduction.objects.get(name = name)
            product_items = OwnProductionItem.objects.filter(own_production = product )

            with transaction.atomic():
                total_price = 0.0
                for item in product_items:
                    good = Good.objects.get(name = item)
                    needed_quantity = item.quantity * quantity
                    actual_quantity = check_good_shortage_quantity(good)

                    if actual_quantity < needed_quantity:
                        return JsonResponse({'status': 'error', 'data': 'Недостатня кіл-ть' + str(item)})

                    good_on_stock = Stock.objects.filter(good_id=good).order_by('date')

                    
                    
                    for good in good_on_stock:

                        total_price += good.price * item.quantity
                    
                    write_off_tmc_from_stock(good, needed_quantity)
                    add_record_in_write_off(request, good, needed_quantity, f"Створення {name}")

                add_good = Good.objects.get(name = name)
                add_own_product_to_stock(add_good, quantity, total_price, storage)
            



            

            return JsonResponse({'message': 'Success'})
    except Exception as error:

        return JsonResponse({'status': 'error', 'data': str(error)}, status=500)
        