from decimal import Decimal
from django.shortcuts import render

# Create your views here.
from django.shortcuts import render
import json
from django.conf import settings
from django.shortcuts import render
from expenses.models import *
from store.models import *
from masters.models import *
from store.forms import *
from masters.forms import *
import hashlib
import os
from django.conf import settings
from datetime import datetime
from django.utils import timezone
from django.db.models import Max, F, Q
import base64
from django.shortcuts import render
from io import BytesIO
from django.conf import settings
from django.template.loader import get_template
from django.http import HttpResponse,HttpResponseRedirect,JsonResponse
from django.shortcuts import get_object_or_404
from django.templatetags.static import static
from xhtml2pdf import pisa
from num2words import num2words
from django.contrib.staticfiles import finders
from common.utils import *
from ledger.views import create_ledger_master_and_opening_balance
#```````````````````````````````````````````````````````````**STORES**````````````````````````````````````````````````````````````````````````````````

def stores(request):
    if 'user_id' in request.session:
        user_type = request.session.get('user_type')
        is_ho = request.session.get("is_ho")
        if user_type == 'admin':
            cmpy = select_row(company_table, {'id':1})  
            branch = selectList(branch_table, {'is_ho':1}, order_by='name')
            role = selectList(role_table, {'role_type':'store'}, order_by='name')
            if is_ho == 1:
                bank = selectList(bank_table, order_by='name')
            else:
                bank = selectList(bank_table, {'is_default':1}, order_by='name')
            return render(request, 'store.html', {'company': cmpy,'branch':branch,'role':role,'bank':bank})
        else:
            return HttpResponseRedirect("/")
    else:
        return HttpResponseRedirect("/")
    

def store_view(request):  
    role_id = request.session.get('role_id')
    has_access, error_message = check_user_access(role_id, 'store', "read")

    if not has_access:
        return JsonResponse({'message': 'permission', 'error_message': 'You do not have permission to view the store details'})

    data = list(selectList(branch_table).values())
    formatted = [
        {
            'id': index + 1,
            'action': '<button type="button" onclick="edit_data(\'{}\')" class="btn btn-outline-success btn-sm p-1"><i class="fas fa-edit"></i></button> \
                       <button type="button" onclick="delete_data(\'{}\')" class="btn btn-outline-danger btn-sm p-1"> <i class="fas fa-trash-alt"></i></button>\
                       <button type="button" onclick="employee_data(\'{}\')" class="btn btn-outline-secondary btn-sm p-1">Employee</button>'.format(item['id'], item['id'], item['id']), 
            'head': getItemNameById(branch_table, item['ho_branch_id']) if item['ho_branch_id'] else '-', 
            'store': item['branch_code'] if item['branch_code'] else '-', 
            'prefix': item['prefix'] if item['prefix'] else '-', 
            'name': item['name'] if item['name'] else '-', 
            'email': item['email'] if item['email'] else '-', 
            'phone': item['phone'] if item['phone'] else '-', 
            'city': item['city'] if item['city'] else '-', 
            'person': item['contact_person'] if item['contact_person'] else '-', 
            'receivable': item['receivable'] if item['receivable'] else '-', 
            'payable': item['payable'] if item['payable'] else '-', 
            'incharge': getNameByBadge(employee_table, item['branch_incharge_id'])  if item['branch_incharge_id'] else '-', 
            'status': '<span class="badge text-bg-success">Active</span>' if item['is_active'] else '<span class="badge text-bg-danger">Inactive</span>'  # Assuming is_active is a boolean field
        } 
        for index, item in enumerate(data)
    ]
    return JsonResponse({'data': formatted})



def store_edit(request):
    if request.headers.get('x-requested-with') == 'XMLHttpRequest' and request.method == "POST":
        branch_id = request.POST.get('id')        
        branch = select_row(branch_table, {'id': branch_id})
        employees = selectList(employee_table, {'branch_id': branch_id}, order_by='name' , fields=['id', 'name'])


        if branch:
            vendor_data = {
                'id': branch.id,
                'established_date': branch.established_date,
                'ho_branch_id': branch.ho_branch_id,
                'name': branch.name,
                'prefix': branch.prefix,
                'branch_code': branch.branch_code,
                'is_ho': branch.is_ho,
                'is_store': branch.is_store,
                'is_franchise': branch.is_franchise,
                'city': branch.city,
                'state': branch.state,
                'pincode': branch.pincode,
                'description': branch.pincode,
                'contact_person': branch.contact_person,
                'email': branch.email,
                'phone': branch.phone,
                'branch_incharge_id': branch.branch_incharge_id,
                'is_active': branch.is_active,
                'address_line_1': branch.address_line1,
                'address_line_2': branch.address_line2,
                'captial': branch.captial,
                'employees': list(employees),  
                'receivable': branch.receivable,
                'payable': branch.payable,
                'bank_id': branch.bank_id,
                'bank_opening': branch.bank_opening,
            }
            return JsonResponse(vendor_data)
        else:
            return JsonResponse({'error': 'Vendor not found'}, status=404)


from django.http import JsonResponse
from django.utils import timezone
from django.db import transaction
import hashlib

def store_add(request):
    if request.method == 'POST':
        try:
            with transaction.atomic():
                user_id = request.session.get('user_id')           
                company_id = request.session.get('company_id') 
                role_id = request.session.get('role_id')

                has_access, error_message = check_user_access(role_id, 'store', "create")

                if not has_access:
                    return JsonResponse({'message': 'permission', 'error_message': 'You do not have permission to add store details'})

                form = storeform(request.POST, request.FILES)
                date_time = timezone.localtime(timezone.now())
                if not form.is_valid():
                    errors = form.errors.as_json()
                    return JsonResponse({'message': 'form_error', 'errors': errors}, status=400)

                if email := request.POST.get('email'):
                    if branch_table.objects.filter(email=email, status=1).exists():
                        return JsonResponse({'message': 'info', 'error_message': 'Email already exists for this store'}, status=400)
                
                if request.POST.get('is_ho') == '1':
                    existing_ho = branch_table.objects.filter(is_ho=1, status=1)
                    if existing_ho.exists():
                        return JsonResponse({
                            'message': 'info',
                            'error_message': 'A Head Office already exists. Only one Head Office is allowed.'
                        }, status=400)

                # Prepare store (branch) instance
                category = form.save(commit=False)
                fyf_name = request.session.get('fyf')
                financial_year = calculate_financial_year(fyf_name)

                # Extract form data
                established = request.POST.get('established')
                store_id = request.POST.get('store_id') or 0
                captial = request.POST.get('captial') or 0
                name = request.POST.get('name')
                prefix = request.POST.get('prefix')
                branch_code = int(request.POST.get('branch_code') or 0)
                is_ho = request.POST.get('is_ho')
                role_id = request.POST.get('role_id')
                city = request.POST.get('city')
                state = request.POST.get('state')
                pincode = request.POST.get('pincode')
                person = request.POST.get('person')
                phone = request.POST.get('phone')
                email = request.POST.get('email')
                pwd = request.POST.get('pwd')
                store_type = request.POST.get('store_type') 
                receivable = request.POST.get('receivable') or 0
                payable = request.POST.get('payable') or 0
                is_store = 1 if store_type == "store" else 0
                is_franchise = 1 if store_type == "franchise" else 0
                address1 = request.POST.get('address1', '').strip()
                address2 = request.POST.get('address2', '').strip()
                bank_id = request.POST.get('bank_id') or 0
                bank_opening = request.POST.get('bank_opening') or 0
                # Save store (branch) entry
                category.num_series = generate_num_series(branch_table)
                category.bank_id = bank_id
                category.bank_opening = bank_opening
                category.company_id = company_id
                category.is_store = is_store
                category.is_franchise = is_franchise
                category.ho_branch_id = store_id
                category.established_date = normalize_date(established)
                category.name = name
                category.prefix = prefix
                category.branch_code = branch_code
                category.contact_person = person
                category.phone = phone
                category.email = email
                category.password = hashlib.md5(pwd.encode()).hexdigest()
                category.address_line1 = address1
                category.address_line2 = address2
                category.city = city
                category.state = state
                category.pincode = pincode if pincode else 0
                category.is_ho = is_ho
                category.receivable = receivable
                category.payable = payable
                category.created_by = user_id
                category.updated_by = user_id
                category.is_active = 1
                category.status = 1
                category.captail = captial
                category.created_on = format_datetime(date_time)
                category.updated_on = format_datetime(date_time)
                category.save()

                branch_id = category.id

                if Decimal(str(payable)) != 0 or Decimal(str(receivable)) != 0:
                    create_ledger_master_and_opening_balance(
                        current_fy=financial_year,
                        branch_id=branch_id,
                        master_id=branch_id,
                        master_name=category.name,
                        ledger_type="branch",
                        ledger_mode="branch",
                        payable=payable,
                        receivable=receivable,
                        created_by=user_id,
                        updated_by=user_id,
                    )

                if Decimal(str(bank_opening)) != 0:
                    bank_name = ""
                    if bank_id:
                        bank_obj = bank_table.objects.filter(id=bank_id).first()
                        bank_name = bank_obj.name if bank_obj else ""

                    create_ledger_master_and_opening_balance(
                        current_fy=financial_year,
                        branch_id=branch_id,
                        master_id=bank_id,
                        master_name=bank_name,
                        ledger_type="bank",
                        ledger_mode="bank",
                        payable=bank_opening,
                        receivable=0,
                        created_by=user_id,
                        updated_by=user_id,
                    )

                # Save default employee (branch incharge)
                employee_code = generate_branch_code(branch_id)

                employee = employee_table(
                    employee_code=employee_code,
                    num_series=generate_num_series(employee_table),
                    company_id=0,
                    role_id=role_id,
                    branch_id=branch_id,
                    name=person,
                    email=email,
                    password=hashlib.md5(pwd.encode()).hexdigest(),
                    address_line1=address1,
                    address_line2=address2,
                    mobile=phone,
                    city=city,
                    state=state,
                    pincode=int(pincode) if pincode else None,
                    photo='',
                    is_pos=1,
                    is_admin=0,
                    is_active=1,
                    status=1,
                    created_on=format_datetime(date_time),
                    updated_on=format_datetime(date_time),
                    created_by=user_id,
                    updated_by=user_id
                )
                employee.save()

                category.branch_incharge_id = employee.id
                category.save()

                

                return JsonResponse({'message': 'success'})

        except Exception as e:
            return JsonResponse({'message': 'exception', 'error': str(e)}, status=500)


def store_update(request):
    if request.method == "POST":
        try:
            with transaction.atomic():
                category_id = int(request.POST.get('id'))
                category = branch_table.objects.get(id=category_id)
                
                old_payable = category.payable or 0
                old_receivable = category.receivable or 0
                old_bank_id = category.bank_id or 0
                old_bank_opening = category.bank_opening or 0

                form = storeform(request.POST, request.FILES, instance=category)
                role_id = request.session.get('role_id')
                has_access, error_message = check_user_access(role_id, 'store', "update")

                if not has_access:
                    return JsonResponse({'message': 'permission', 'error_message': 'You do not have permission to update store details'})
                
                date_time = timezone.localtime(timezone.now())
                
                if form.is_valid():
                    updated_category = form.save(commit=False)
                    established = request.POST.get('established') 
                    store_id = request.POST.get('store_id') or 0
                    captial = request.POST.get('captial') or 0.00
                    bank_opening = request.POST.get('bank_opening') or 0.00
                    bank_id = request.POST.get('bank_id') or 0
                    name = request.POST.get('name')
                    prefix = request.POST.get('prefix')
                    branch_code = int(request.POST.get('branch_code') or 0)
                    person = request.POST.get('person')
                    phone = request.POST.get('phone')
                    email = request.POST.get('email')
                    address1 = request.POST.get('address1')
                    address2 = request.POST.get('address2')
                    is_active = request.POST.get('is_active') or 1
                    incharge_id = request.POST.get('incharge_id')
                    store_type = request.POST.get('store_type') or "store"
                    receivable = request.POST.get('receivable') or 0
                    payable = request.POST.get('payable') or 0
                    is_store = 1 if store_type == "store" else 0
                    is_franchise = 1 if store_type == "franchise" else 0

                    if email and branch_table.objects.filter(email=email, status=1).exclude(id=category_id).exists():
                        return JsonResponse({'message': 'info', 'error_message': 'Email already exists for this store'}, status=400)
                    
                    is_ho = request.POST.get('is_ho') or 0

                    if str(is_ho) == '1' and branch_table.objects.filter(is_ho=1, status=1).exclude(id=category_id).exists():
                        return JsonResponse({'message': 'info', 'error_message': 'Another store is already marked as Head Office. Only one Head Office is allowed.'})

                    updated_category.ho_branch_id = store_id
                    updated_category.bank_id = bank_id
                    updated_category.bank_opening = bank_opening

                    updated_category.established_date = normalize_date(established)
                    updated_category.name = name
                    updated_category.receivable = receivable
                    updated_category.payable = payable
                    updated_category.is_store = is_store
                    updated_category.captial= captial
                    updated_category.is_franchise = is_franchise
                    updated_category.prefix = prefix
                    updated_category.branch_code = branch_code
                    updated_category.contact_person = person
                    updated_category.phone = phone
                    updated_category.email = email
                    updated_category.address_line1 = address1
                    updated_category.address_line2 = address2
                    updated_category.is_ho = is_ho  
                    updated_category.branch_incharge_id = incharge_id           
                    updated_category.is_active = is_active            
                    updated_category.updated_by = request.session.get('user_id')
                    updated_category.updated_on = format_datetime(date_time)
                    updated_category.save()

                    fyf_name = request.session.get('fyf')
                    financial_year = calculate_financial_year(fyf_name)

                    if Decimal(str(payable)) != 0 or Decimal(str(receivable)) != 0:
                        create_ledger_master_and_opening_balance(
                            current_fy=financial_year,
                            branch_id=category_id,
                            master_id=category_id,
                            master_name=updated_category.name,
                            ledger_type="branch",
                            ledger_mode="branch",
                            payable=payable,
                            receivable=receivable,
                            created_by=request.session.get('user_id'),
                            updated_by=request.session.get('user_id'),
                            update=True
                        )

                    if Decimal(str(bank_opening)) != 0:
                        bank_name = ""
                        if bank_id:
                            bank_obj = bank_table.objects.filter(id=bank_id).first()
                            bank_name = bank_obj.name if bank_obj else ""

                        create_ledger_master_and_opening_balance(
                            current_fy=financial_year,
                            branch_id=category_id,
                            master_id=int(bank_id),
                            master_name=bank_name,
                            ledger_type="bank",
                            ledger_mode="bank",
                            payable=bank_opening,
                            receivable=0,
                            created_by=request.session.get('user_id'),
                            updated_by=request.session.get('user_id'),
                            update=True
                        )

                    return JsonResponse({'message': 'success'})
                else:
                    errors = form.errors.as_json()
                    return JsonResponse({'message': 'error', 'errors': errors})
        except Exception as e:
            return JsonResponse({'message': 'exception', 'error': str(e)})





def store_delete(request):
    if request.method == 'POST':
        data_id = request.POST.get('id')    
        role_id = request.session.get('role_id')
        has_access = check_user_access(role_id, 'store', "delete")

        if not has_access:
            return JsonResponse({'message': 'permission', 'error_message': 'You do not have permission to delete store details'})
               
        try:
            updated = branch_table.objects.filter(id=data_id).update(status=0)
            if updated:
                return JsonResponse({'message': 'yes'})
            else:
                return JsonResponse({'message': 'no such data'})
        except Exception as e:
            return JsonResponse({'message': 'exception', 'error': str(e)})

    return JsonResponse({'message': 'Invalid request method'})



def check_branch_code(request):
    if 'user_id' in request.session:
        sku = request.GET.get('code')
        item_id = request.GET.get('id')

        if not sku:
            return JsonResponse({'exists': False})

        query = selectList(branch_table, {'branch_code': sku})

        if item_id:
            query = query.exclude(id=item_id)

        if query.exists():
            return JsonResponse({'exists': True})

        return JsonResponse({'exists': False})
    else:
        return JsonResponse({'message': 'Unauthorized access'})
    



def check_branch_email(request):
    if 'user_id' in request.session:
        mail = request.GET.get('email')
        item_id = request.GET.get('id') 

        if not mail:
            return JsonResponse({'exists': False}) 

        query = selectList(branch_table, {'email':mail})
        if item_id:
            query = query.exclude(id=item_id)

        if query.exists():
            return JsonResponse({'exists': True})
        
        return JsonResponse({'exists': False})
    else:
        return JsonResponse({'message': 'Unauthorized access'})
    
def check_branch_name(request):
    if 'user_id' in request.session:
        name = request.GET.get('name')
        item_id = request.GET.get('id') 

        if not name:
            return JsonResponse({'exists': False}) 

        query = selectList(branch_table, {'name':name})
        if item_id:
            query = query.exclude(id=item_id)

        if query.exists():
            return JsonResponse({'exists': True})
        
        return JsonResponse({'exists': False})
    else:
        return JsonResponse({'message': 'Unauthorized access'})
    



def store_company(request):
    if 'user_id' in request.session:
        user_type = request.session.get('user_type')
        if user_type == 'stores':
            branch_id = request.session.get('branch_id')
            company = select_row(branch_table, {'id':branch_id})
            branch = selectList(branch_table,{'is_ho':1}, order_by='name')
            category = selectList(category_table, order_by='name')
            employee = selectList(employee_table, {'branch_id':branch_id}, order_by='name')
            bank = selectList(bank_table, {'is_default':1}, order_by='name')
            return render(request, 'store_company.html', {'company': company,'category':category,'employee':employee,'branch':branch,'bank':bank})
        if user_type == 'wholesale':
            branch_id = request.session.get('branch_id')
            company = select_row(branch_table, {'id':branch_id})
            branch = selectList(branch_table,{'is_ho':1}, order_by='name')
            category = selectList(category_table, order_by='name')
            employee = selectList(employee_table, {'branch_id':branch_id}, order_by='name')
            bank = selectList(bank_table, {'is_default':1}, order_by='name')
            return render(request, 'internal_wholesale/company.html', {'company': company,'category':category,'employee':employee,'branch':branch,'bank':bank})

        else:
            return HttpResponseRedirect("/")
    else:
        return HttpResponseRedirect("/")

