# -*- coding: utf-8 -*-
from django.shortcuts import render,redirect, get_object_or_404
from django.contrib import messages
from django.http import JsonResponse, HttpResponse
from django.db import transaction

import json
import os
import pandas as pd
from io import StringIO
from utils.utils import remove_spaces_from_string
from action_history.views import user_action_audit, changes_history

from .forms import AddGoodCategoryForm, AddStorageFacilityForm, AddGoodForm, AddVendorForm
from .models import GoodCategory, StorageFacility, Good, Vendor, VendorContact

from .filters import GoodFilter
# Create your views here.


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

#### GOOD CATEGORY #################
def good_category(request):
    categories = GoodCategory.objects.all()
    if request.method == "POST":
        form = AddGoodCategoryForm(request.POST)
        if form.is_valid():
            category_name = form.cleaned_data['name']
            if GoodCategory.objects.filter(name=category_name).exists():
                messages.error(request, "Категорія вже додана !")
                return redirect('good-category')
            else:
                form.instance.created_by = request.user
                form.save()
                messages.success(request, "Збереженно успішно!")
                return redirect('good-category')
    else:
        form = AddGoodCategoryForm()
    return render(request, 'management/good-category.html', context={'form': form, 'categories': categories})

def good_category_update(request, id):
    category = get_object_or_404(GoodCategory, id=id)
    if request.method == "POST":
        form = AddGoodCategoryForm(request.POST, instance=category)
        if form.is_valid():
            category_name = form.cleaned_data['name']
            if GoodCategory.objects.filter(name=category_name).exists():
                messages.error(request, "Категорія вже існує !")
                form = AddGoodCategoryForm(instance = category)
                return render(request, 'management/good-category.html', {'form': form})
            form.save()
            messages.success(request, "Оновлено успішно!")
            return redirect(f'good-category')
            
    else:
        form = AddGoodCategoryForm(instance = category)
    return render(request, 'management/good-category.html', {'form': form})

def good_category_delete(request):
    data = json.loads(request.body)
    try:
        category_id = data.get("category_id")
        with transaction.atomic():
            category = get_object_or_404(GoodCategory, id=category_id)
            category.delete()
            # action_history(request.user, f"Видалення постачальника {vendor.name}", "OK")
            return JsonResponse({'message': 'Success'})
    except Exception as error:
        category = get_object_or_404(Vendor, id=category_id)
        # action_history(request.user, f"Видалення обьєкт {vendor.name}", {error})
        return JsonResponse({'message': 'Error', 'data': str(error)})

def category_search(request):
    try:
        if request.method == "POST":
            data = json.loads(request.body)
            category_name = data['data'].get("category_name")
            if not category_name:
                return  JsonResponse({'message': 'Error','data':str('Empty_value')})
            category = GoodCategory.objects.filter(name = category_name).values('id','name')
            if category:
                category_item = category.first()
                category_item = {
                    'category_id': category_item.get('id'),
                    'name': category_item.get('name'),
                }
            return JsonResponse({
                'message': 'Success',
                'category_item':category_item
                }, safe=False)
    except Exception as error:
        return  JsonResponse({'message': 'Error','data':str(error)})

#### END GOOD CATEGORY #################

#### STORAGE #################


def storage(request):
    try:   
        if request.method == "POST":
            form_data = json.loads(request.body)
            print(f"form_data ==> {form_data}")
            form = AddStorageFacilityForm(form_data)
            if StorageFacility.objects.filter(name=form_data['name']).exists():
                return JsonResponse({'message': 'Error', 'data':'Склад вже додано!'})
            if form.is_valid():
                form.instance.created_by = request.user
                form.save()
                # action_history(request.user, f"Створення складу  {form_data['name']}", "OK")
                return JsonResponse({'message': 'Success'})
        elif request.method == "GET":  
            storages = StorageFacility.objects.all()[:5]
            return render(request, 'management/storage.html', context={'storages': storages})
    except Exception as error:
        print(f" storage ERROR ==> {error}")
        # action_history(request.user, f"Створення складу {form_data['name']}", {error})
    
@transaction.atomic
def storage_update(request, id):
    try:
        storage = StorageFacility.objects.select_for_update().get(id=id)
        if request.method == 'GET':
            return render(request, 'management/storage_update.html', {"storage":storage})
        elif request.method == 'POST':
            data = request.POST
            name = remove_spaces_from_string(data.get('name').strip())
            location = data.get('location')
            print(f" name ==> {name}, location ==> {location}")
            storage.name = name
            storage.location = location
            storage.save()
            return redirect('storage')
        # action_history(request.user, f"Оновлення складу {storage.name}", "OK")
        return JsonResponse({'message': 'Success', 'data':data})
    except Exception as error:
        print(f" storage_update ERROR ==> {error}")
        # action_history(request.user, f"Оновлення складу {storage.name}", {error})



def storage_delete(request):
    try:
        data = json.loads(request.body)
        storage_id = data.get('storageId')
        storage = get_object_or_404(StorageFacility, id=storage_id)
        storage.delete()
        # action_history(request.user, f"Видалення складу {storage.name}", "OK")
        return JsonResponse({'message': 'Success'})
    except Exception as error:
        # action_history(request.user, f"Видалення складу {storage.name}", {error})
        return JsonResponse({'message': 'Error', 'data': str(error)})
    
def storage_search(request):
    try:
        if request.method == "POST":
            data = json.loads(request.body)
            storage_name = data['data'].get("storage_name")
            if not storage_name:
                return  JsonResponse({'message': 'Error','data':str('Empty_value')})
            storage = StorageFacility.objects.filter(name = storage_name).values('id','name')
            if storage:
                storage_item = storage.first()
                storage_item = {
                    'storage_id': storage_item.get('id'),
                    'name': storage_item.get('name'),
                }
            return JsonResponse({
                'message': 'Success',
                'storage_item':storage_item
                }, safe=False)
    except Exception as error:
        return  JsonResponse({'message': 'Error','data':str(error)})

#### END STORAGE #################

#### TMC #################
def tmc(request):
    form_add_tmc = AddGoodForm()
    
    if request.method == "POST" and ('save_changes' in request.POST):
        goods = Good.objects.all()
        form_add_tmc = AddGoodForm(request.POST, request.FILES)
        if form_add_tmc.is_valid(): 
            name = form_add_tmc.cleaned_data['name']
            name = remove_spaces_from_string(name)
            unit_of_measurement = form_add_tmc.cleaned_data['unit_of_measurement'].strip('')
            form_add_tmc.instance.created_by = request.user
            if Good.objects.filter(name = name, unit_of_measurement = unit_of_measurement).exists():
                messages.error(request, "ТМЦ вже додано !")
                return redirect('tmc')
            else:
                name = form_add_tmc.cleaned_data['name']
                name = remove_spaces_from_string(name)
                form_add_tmc.instance.name = name
                form_add_tmc.save()
                new_value = list(Good.objects.filter(id=form_add_tmc.instance.id).values('name',))
                new_record = json.dumps(new_value)
                tmc_name = new_value
                # action_history("Створено", form_add_tmc.instance.id, tmc_name, request.user, json.dumps([{"name":""}]), new_record)
                # def action_history(action, parent, name, created_by, old_record, new_record):
                return redirect('tmc')
        else:
            return render(request, 'management/tmc.html', context={"form_add_tmc":form_add_tmc})
        # return render(request, 'management/tmc.html', context={'form_add_tmc': form_add_tmc, 'goods': goods, 'goods_filter': goods_filter})
    elif request.method == "POST":
        goods = Good.objects.all()
        goods_filter = GoodFilter(request.POST, queryset = goods)
        goods = goods_filter.qs
        return render (request, 'management/tmc.html', context={'form_add_tmc':form_add_tmc, 'goods':goods, 'goods_filter':goods_filter})
    else:
        goods_filter = GoodFilter(request.POST)
        goods = Good.objects.all().order_by('-created_at')[:10]
        return render (request, 'management/tmc.html', context={'form_add_tmc':form_add_tmc, 'goods':goods, 'goods_filter':goods_filter})


def search_tmc(request):
    if request.method == "POST": 
        goods = Good.objects.all()
        goods_filter = GoodFilter(request.POST, queryset = goods)
        goods = goods_filter.qs
        return render(request, 'management/tmc.html', context={'goods':goods,'goods_filter':goods_filter}) 


def tmc_update(request, id):
    tmc = Good.objects.get(id=id)
    old = list(Good.objects.filter(id=id).values('name', 'unit_of_measurement'))
    old_value = json.dumps(old)
    # old_value = serializers.serialize('json', old)
    if request.method == 'GET':
        return render(request, 'management/tmc_detail.html', {"tmc":tmc})
    elif request.method == 'POST':
        data=request.POST

        name=data.get('name')
        unit_of_measurement=data.get('unit_of_measurement')
        article=data.get('article')
        description=data.get('description')
        photo=request.FILES.get('photo')
        category=data.get('category')
        print(f" category ==> {category}")
        tmc.name=name
        tmc.unit_of_measurement=unit_of_measurement 
        tmc.article=article
        tmc.description=description
        tmc.category=GoodCategory.objects.get(name=category)

        if photo:
            tmc.photo=photo
    
        tmc.save()
        # new_value = serializers.serialize('json', Good.objects.filter(id=id))
        new = list(Good.objects.filter(id=id).values('name', 'unit_of_measurement'))

        new_value = json.dumps(new)
        # def action_history(action, parent, name, created_by, old_record, new_record):
        # action_history("Оновлено", tmc.id, tmc.name, request.user, old_value, new_value)

        # action_history(request.user, f"Оновленно ТМЦ  {name}", "OK")
        # action_history("Оновлено", tmc.id , request.user, field="name", old_record=old_value, new_record=new_value, result="Ok")
        # audit_changes(old_value, new_value)
        return redirect('tmc')

def tmc_delete(request):
    try:
        data = json.loads(request.body)
        tmc_id = data.get('tmc_id')
        good = get_object_or_404(Good, id=tmc_id)
        
        if good.photo and hasattr(good.photo, 'path') and os.path.exists(good.photo.path):
            os.remove(good.photo.path)
            
            folder_path = os.path.dirname(good.photo.path)
            if os.path.exists(folder_path) and not os.listdir(folder_path):
                os.rmdir(folder_path)
        good.delete()
        # action_history("Видалено", good.name, good.name, request.user, json.dumps([{"name":good.name}]), json.dumps([{"name":""}]))
        # def action_history(action, parent, name, created_by, old_record, new_record):
        # action_history(request.user, f"Видалено ТМЦ {good.name}", "OK")
        return JsonResponse({'message': 'Success'})
    except Exception as error:
        # action_history(request.user, f"Видалення ТМЦ {good.name}", {error})
        return JsonResponse({'message': 'Error', 'data': str(error)})


#### END TMC #################

#### VENDOR #################
def process_vendor_contact_items(vendor_id, items):
    try:
        contacts_items_delete = VendorContact.objects.filter(vendor=vendor_id)
        contacts_items_delete.delete()      
        for _, row in items.iterrows():

            contact_email = row['Email']
            contact_phone = row['Телефон']
            contact_name = row['Імя']
            contact_position = row['Посада']

            contact_item = VendorContact.objects.create(
                vendor=Vendor.objects.get(id=vendor_id),
                email = contact_email,
                phone = contact_phone,
                manager = contact_name,
                position  = contact_position,
            )
    except Exception as error:
        raise error    

def vendor(request):
    if request.method == "POST":
        data = json.loads(request.body)
        name = data['data'].get("name")
        location = data['data'].get("location")
        config_name = data['data'].get("config_name")
        with transaction.atomic():
            vendor = Vendor.objects.create(
                name=name,
                location=location,
                config_name=config_name,
                created_by=request.user
            )
            table =  data['data'].get("table")
            html_buffer = StringIO(table)
            items = pd.read_html(html_buffer)[0]

            process_vendor_contact_items(vendor.id, items)
            # action_history(request.user, f"Додано обьєкт {name}", "OK")
            return JsonResponse({'message': 'Success'})
    else:
        vendors = Vendor.objects.all()[:5]
        form = AddVendorForm()
    return render (request, 'management/vendor.html', context={'form':form, 'vendors':vendors})

def vendor_update(request, id):
    try:
        vendor = get_object_or_404(Vendor, id=id)
        contacts = None
        if VendorContact.objects.filter(vendor = vendor.id).exists():
            contacts =  VendorContact.objects.filter(vendor = vendor.id)
        if request.method == 'GET':
            return render(request, 'management/vendor_update.html', {"vendor":vendor,"contacts":contacts})
        elif request.method == 'POST':
            data = json.loads(request.body)
            name =  data['data'].get('name')
            location =  data['data'].get('location')
            config_name =  data['data'].get('config_name')
            table =  data['data'].get("table")
            html_buffer = StringIO(table)
            items = pd.read_html(html_buffer)[0]
            with transaction.atomic():
                vendor.name = name
                vendor.location = location
                vendor.config_name = config_name
                
                process_vendor_contact_items(vendor.id, items)

                vendor.save()

                # action_history(request.user, f"Оновлення постачальника {vendor.name}", "OK")
                return JsonResponse({'message': 'Success'})
    except Exception as error:
        vendor = get_object_or_404(Vendor, id=id)
        # action_history(request.user, f"Оновлення постачальника {vendor.name}", {error})
        return JsonResponse({'message': 'Error', 'data':str(error)})


def vendor_delete(request):
    data = json.loads(request.body)
    try:
        vendor_id = data.get("vendor_id")
        with transaction.atomic():

            contacts = VendorContact.objects.filter(vendor = vendor_id)
            if contacts:
                for item in contacts:
                    item.delete()
            vendor = get_object_or_404(Vendor, id=vendor_id)
            vendor.delete()
            # action_history(request.user, f"Видалення постачальника {vendor.name}", "OK")
            return JsonResponse({'message': 'Success'})
    except Exception as error:
        vendor = get_object_or_404(Vendor, id=vendor_id)
        # action_history(request.user, f"Видалення обьєкт {vendor.name}", {error})
        return JsonResponse({'message': 'Error', 'data': str(error)})

def vendor_search(request):
    try:
        if request.method == "POST":
            data = json.loads(request.body)
            vendor_name = data['data'].get("vendor_name")
            if not vendor_name:
                return  JsonResponse({'message': 'Error','data':str('Empty_value')})
            vendor = Vendor.objects.filter(name = vendor_name).values('id','name')
            if vendor:
                vendor_item = vendor.first()
                vendor_item = {
                    'vendor_id': vendor_item.get('id'),
                    'name': vendor_item.get('name'),
                }
                
            return JsonResponse({
                'message': 'Success',
                'vendor_item':vendor_item
                }, safe=False)
    except Exception as error:
        return  JsonResponse({'message': 'Error','data':str(error)})

#### END VENDOR #################


#### UTILS #################
    

def checkTmcByNameAndUnitOfMeasurement(request):
    if request.method == "POST":
        data = json.loads(request.body)
        name = data.get('name', '')
        name = remove_spaces_from_string(name)
        unit_of_measurement = data.get('UnitOfMeasuremen', '')
        if name and unit_of_measurement:
            if Good.objects.filter(name=name, unit_of_measurement=unit_of_measurement).exists():
                return JsonResponse({'result': "ok"})
            else:
                return JsonResponse({'result': "error"})

def addTmcFromReceiptTable(request):
    try:
        data = json.loads(request.body)
        name, quantity, unit_of_measurement, price, total, action = data['data']
        if Good.objects.filter(name=name, unit_of_measurement=unit_of_measurement).exists():
            return JsonResponse({'result': "ok"})
        good = Good.objects.create(
                    name = remove_spaces_from_string(name),
                    unit_of_measurement = unit_of_measurement,
                    created_by = request.user,
                )
        # action_history(request.user, f"Додавання ТМЦ з таблиці закупок {name}", "OK")
        return JsonResponse({'result': "ok"})
    except Exception as error:
        # action_history(request.user, f"Додавання ТМЦ з таблиці закупок {name}", {error})
        return JsonResponse({'message': 'error','data':str(error)})

def addTmcFromAdditionalPurchasesTable(request):
    try:
        data = json.loads(request.body)
        name, unit_of_measurement, quantity, price, utilized, bt1, bt2 = data['data']
        if Good.objects.filter(name=name, unit_of_measurement=unit_of_measurement).exists():
            return JsonResponse({'result': "ok"})
        good = Good.objects.create(
                    name = remove_spaces_from_string(name),
                    unit_of_measurement = unit_of_measurement,
                    created_by = request.user,
                )
        # action_history(request.user, f"Додавання ТМЦ з дозакупок {name}", "OK")
        return JsonResponse({'result': "ok"})
    except Exception as error:
        action_history(request.user, f"Додавання ТМЦ з таблиці закупок {name}", {error})
        return JsonResponse({'message': 'error','data':str(error)})
#### END UTILS #################





