from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from django.views.generic import ListView
from django.db import transaction
from .models import (
    Sale, SaleLine, Product, Customer, ProductCategory, Payment, PaymentMethods, ReconciliationJar)
from .forms import (
    ImportProductsForm,
    ImportCustomersForm,
    PurchaseForm,
    SaleLineFormSet,
    PurchaseSummaryForm)
import csv
import io
import json
from decimal import Decimal
class DecimalEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Decimal):
            return float(obj)
        return json.JSONEncoder.default(self, obj)
def index(request):
    return render(request, 'don_confiao/index.html')
def buy(request):
    if request.method == "POST":
        sale_form = PurchaseForm(request.POST)
        line_formset = SaleLineFormSet(request.POST)
        sale_summary_form = PurchaseSummaryForm(request.POST)
        forms_are_valid = all([
            sale_form.is_valid(),
            line_formset.is_valid(),
            sale_summary_form.is_valid()
        ])
        payment_method = request.POST.get('payment_method')
        valid_payment_methods = [PaymentMethods.CASH]
        valid_payment_method = payment_method in valid_payment_methods
        if forms_are_valid:
            with transaction.atomic():
                sale = sale_form.save()
                line_formset.instance = sale
                line_formset.save()
                Payment.total_payment_from_sale(
                    payment_method,
                    sale
                )
            return HttpResponseRedirect("compras")
    else:
        sale_form = PurchaseForm()
        line_formset = SaleLineFormSet()
        sale_summary_form = PurchaseSummaryForm()
    return render(
        request,
        'don_confiao/purchase.html',
        {
            'sale_form': sale_form,
            'linea_formset': line_formset,
            'summary_form': sale_summary_form,
            'list_products': json.dumps(Product.to_list(), cls=DecimalEncoder),
        }
    )
def purchases(request):
    purchases = Sale.objects.all()
    context = {
        "purchases": purchases,
    }
    return render(request, 'don_confiao/purchases.html', context)
def products(request):
    return JsonResponse(Product.to_list(), safe=False)
def import_products(request):
    if request.method == "POST":
        form = ImportProductsForm(request.POST, request.FILES)
        if form.is_valid():
            handle_import_products_file(request.FILES["csv_file"])
            return HttpResponseRedirect("productos")
    else:
        form = ImportProductsForm()
    return render(
        request,
        "don_confiao/import_products.html",
        {'form': form}
    )
def import_customers(request):
    if request.method == "POST":
        form = ImportCustomersForm(request.POST, request.FILES)
        if form.is_valid():
            handle_import_customers_file(request.FILES["csv_file"])
            return HttpResponseRedirect("productos")
    else:
        form = ImportCustomersForm()
    return render(
        request,
        "don_confiao/import_customers.html",
        {'form': form}
    )
def reconciliations(request):
    return HttpResponse('
Reconciliaciones
')
def purchase_summary(request, id):
    purchase = Sale.objects.get(pk=id)
    return render(
        request,
        "don_confiao/purchase_summary.html",
        {
            "purchase": purchase
        }
    )
def _categories_from_csv_string(categories_string, separator="&"):
    categories = categories_string.split(separator)
    clean_categories = [c.strip() for c in categories]
    return [_category_from_name(category) for category in clean_categories]
def _category_from_name(name):
    return ProductCategory.objects.get_or_create(name=name)[0]
def handle_import_products_file(csv_file):
    data = io.StringIO(csv_file.read().decode('utf-8'))
    reader = csv.DictReader(data, quotechar='"')
    for row in reader:
        product, created = Product.objects.update_or_create(
            name=row['producto'],
            defaults={
                'price': row['precio'],
                'measuring_unit': row['unidad']
            }
        )
        categories = _categories_from_csv_string(row["categorias"])
        product.categories.clear()
        for category in categories:
            product.categories.add(category)
def handle_import_customers_file(csv_file):
    data = io.StringIO(csv_file.read().decode('utf-8'))
    reader = csv.DictReader(data, quotechar='"')
    for row in reader:
        customer, created = Customer.objects.update_or_create(
            name=row['nombre'],
            defaults={
                'email': row['correo'],
                'phone': row['telefono']
            }
        )
def sales_to_tryton_csv(sales):
    tryton_sales_header = [
        "Tercero",
        "Dirección de facturación",
        "Dirección de envío",
        "Descripción",
        "Referencia",
        "Fecha venta",
        "Plazo de pago",
        "Almacén",
        "Moneda",
        "Líneas/Producto",
        "Líneas/Cantidad",
        "Líneas/Precio unitario",
        "Líneas/Unidad",
        "Empresa",
        "Tienda",
        "Terminal de venta",
        "Autorecogida",
        "Comentario"
    ]
    csv_data = [tryton_sales_header]
    for sale in sales:
        sale_lines = SaleLine.objects.filter(sale=sale.id)
        if not sale_lines:
            continue
        lines = []
        first_sale_line = sale_lines[0]
        customer_info = [sale.customer.name] * 3 + [sale.description] * 2
        first_line = customer_info + [
            sale.date.strftime('%Y-%m-%d'),
            "Contado",
            "Almacén",
            "Peso colombiano",
            first_sale_line.product.name,
            first_sale_line.quantity,
            first_sale_line.unit_price,
            "Unidad",
            "TIENDA LA ILUSIÓN",
            "Tienda La Ilusion",
            "La Ilusion",
            True,
            sale.description]
        lines.append(first_line)
        for line in sale_lines[1:]:
            lines.append([""]*9+[
                line.product.name,
                line.quantity,
                line.unit_price,
                "Unidad"]+[""]*5)
        for row in lines:
            csv_data.append(row)
    return csv_data
def exportar_ventas_para_tryton(request):
    if request.method == "GET":
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = "attachment; filename=sales.csv"
        sales = Sale.objects.all()
        csv_data = sales_to_tryton_csv(sales)
        writer = csv.writer(response)
        for row in csv_data:
            writer.writerow(row)
        return response
class ProductListView(ListView):
    model = Product
    template_model = 'don_confiao/product_list.html'
    def get_queryset(self):
        name = self.request.GET.get('name')
        if name:
            return Product.objects.filter(name__icontains=name)
        return Product.objects.all()