package handlers

import (
	"fmt"
	"net/http"
	"strconv"
	"time"

	"erp_system/internal/models"
)

func (h *Handler) OrderList(w http.ResponseWriter, r *http.Request) {
	status := r.URL.Query().Get("status")
	orders, err := models.OrderGetAll(h.DB, status)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	data := map[string]interface{}{
		"Title":        "Orders",
		"Username":     h.getUsername(r),
		"ActivePage":   "orders",
		"Orders":       orders,
		"FilterStatus": status,
	}

	if r.Header.Get("HX-Request") == "true" && r.URL.Query().Get("partial") == "true" {
		h.renderPartial(w, "orders/list.html", "order-table", data)
		return
	}

	h.render(w, []string{"layout.html", "orders/list.html"}, data)
}

func (h *Handler) OrderNew(w http.ResponseWriter, r *http.Request) {
	customers, _ := models.CustomerGetAll(h.DB, "")

	data := map[string]interface{}{
		"Title":      "New Order",
		"Username":   h.getUsername(r),
		"ActivePage": "orders",
		"Order":      &models.Order{OrderDate: time.Now().Format("2006-01-02"), Status: "draft"},
		"Customers":  customers,
		"IsNew":      true,
	}
	h.render(w, []string{"layout.html", "orders/form.html"}, data)
}

func (h *Handler) OrderCreate(w http.ResponseWriter, r *http.Request) {
	customerID, _ := strconv.Atoi(r.FormValue("customer_id"))
	o := &models.Order{
		CustomerID: customerID,
		Status:     "draft",
		OrderDate:  r.FormValue("order_date"),
		Notes:      r.FormValue("notes"),
	}

	if o.CustomerID == 0 {
		customers, _ := models.CustomerGetAll(h.DB, "")
		data := map[string]interface{}{
			"Title":      "New Order",
			"Username":   h.getUsername(r),
			"ActivePage": "orders",
			"Order":      o,
			"Customers":  customers,
			"IsNew":      true,
			"Error":      "Customer is required",
		}
		h.render(w, []string{"layout.html", "orders/form.html"}, data)
		return
	}

	if o.OrderDate == "" {
		o.OrderDate = time.Now().Format("2006-01-02")
	}

	if err := models.OrderInsert(h.DB, o); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	if r.Header.Get("HX-Request") == "true" {
		w.Header().Set("HX-Redirect", fmt.Sprintf("/orders/%d", o.ID))
		return
	}
	http.Redirect(w, r, fmt.Sprintf("/orders/%d", o.ID), http.StatusSeeOther)
}

func (h *Handler) OrderDetail(w http.ResponseWriter, r *http.Request) {
	id, _ := strconv.Atoi(r.PathValue("id"))
	order, err := models.OrderGetByID(h.DB, id)
	if err != nil {
		http.Error(w, "Order not found", http.StatusNotFound)
		return
	}

	data := map[string]interface{}{
		"Title":      fmt.Sprintf("Order #%d", order.ID),
		"Username":   h.getUsername(r),
		"ActivePage": "orders",
		"Order":      order,
	}
	h.render(w, []string{"layout.html", "orders/detail.html"}, data)
}

func (h *Handler) OrderEdit(w http.ResponseWriter, r *http.Request) {
	id, _ := strconv.Atoi(r.PathValue("id"))
	order, err := models.OrderGetByID(h.DB, id)
	if err != nil {
		http.Error(w, "Order not found", http.StatusNotFound)
		return
	}

	if order.Status != "draft" {
		http.Error(w, "Only draft orders can be edited", http.StatusBadRequest)
		return
	}

	customers, _ := models.CustomerGetAll(h.DB, "")

	data := map[string]interface{}{
		"Title":      fmt.Sprintf("Edit Order #%d", order.ID),
		"Username":   h.getUsername(r),
		"ActivePage": "orders",
		"Order":      order,
		"Customers":  customers,
		"IsNew":      false,
	}
	h.render(w, []string{"layout.html", "orders/form.html"}, data)
}

func (h *Handler) OrderUpdate(w http.ResponseWriter, r *http.Request) {
	id, _ := strconv.Atoi(r.PathValue("id"))
	customerID, _ := strconv.Atoi(r.FormValue("customer_id"))

	o := &models.Order{
		ID:         id,
		CustomerID: customerID,
		OrderDate:  r.FormValue("order_date"),
		Notes:      r.FormValue("notes"),
	}

	if err := models.OrderUpdate(h.DB, o); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	if r.Header.Get("HX-Request") == "true" {
		w.Header().Set("HX-Redirect", fmt.Sprintf("/orders/%d", id))
		return
	}
	http.Redirect(w, r, fmt.Sprintf("/orders/%d", id), http.StatusSeeOther)
}

func (h *Handler) OrderConfirm(w http.ResponseWriter, r *http.Request) {
	id, _ := strconv.Atoi(r.PathValue("id"))
	if err := models.OrderUpdateStatus(h.DB, id, "confirmed"); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	if r.Header.Get("HX-Request") == "true" {
		w.Header().Set("HX-Redirect", fmt.Sprintf("/orders/%d", id))
		return
	}
	http.Redirect(w, r, fmt.Sprintf("/orders/%d", id), http.StatusSeeOther)
}

func (h *Handler) OrderFulfill(w http.ResponseWriter, r *http.Request) {
	id, _ := strconv.Atoi(r.PathValue("id"))

	// Update status
	if err := models.OrderUpdateStatus(h.DB, id, "fulfilled"); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Generate invoice and GL entries
	if err := models.GenerateInvoiceFromOrder(h.DB, id); err != nil {
		http.Error(w, fmt.Sprintf("Order fulfilled but invoice generation failed: %v", err), http.StatusInternalServerError)
		return
	}

	if r.Header.Get("HX-Request") == "true" {
		w.Header().Set("HX-Redirect", fmt.Sprintf("/orders/%d", id))
		return
	}
	http.Redirect(w, r, fmt.Sprintf("/orders/%d", id), http.StatusSeeOther)
}

func (h *Handler) OrderCancel(w http.ResponseWriter, r *http.Request) {
	id, _ := strconv.Atoi(r.PathValue("id"))
	if err := models.OrderUpdateStatus(h.DB, id, "cancelled"); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	if r.Header.Get("HX-Request") == "true" {
		w.Header().Set("HX-Redirect", fmt.Sprintf("/orders/%d", id))
		return
	}
	http.Redirect(w, r, fmt.Sprintf("/orders/%d", id), http.StatusSeeOther)
}

func (h *Handler) OrderDelete(w http.ResponseWriter, r *http.Request) {
	id, _ := strconv.Atoi(r.PathValue("id"))
	if err := models.OrderDelete(h.DB, id); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	if r.Header.Get("HX-Request") == "true" {
		w.Header().Set("HX-Redirect", "/orders")
		return
	}
	http.Redirect(w, r, "/orders", http.StatusSeeOther)
}

// Order line handlers (HTMX partials)

func (h *Handler) OrderLineAdd(w http.ResponseWriter, r *http.Request) {
	orderID, _ := strconv.Atoi(r.PathValue("id"))
	qty, _ := strconv.ParseFloat(r.FormValue("quantity"), 64)
	price, _ := strconv.ParseFloat(r.FormValue("unit_price"), 64)

	line := &models.OrderLine{
		OrderID:     orderID,
		Description: r.FormValue("description"),
		Quantity:    qty,
		UnitPrice:   price,
	}

	if line.Description == "" || line.Quantity <= 0 {
		http.Error(w, "Description and quantity are required", http.StatusBadRequest)
		return
	}

	if err := models.OrderLineInsert(h.DB, line); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Return updated order detail
	order, err := models.OrderGetByID(h.DB, orderID)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	h.renderPartial(w, "orders/detail.html", "order-lines", order)
}

func (h *Handler) OrderLineDelete(w http.ResponseWriter, r *http.Request) {
	orderID, _ := strconv.Atoi(r.PathValue("id"))
	lineID, _ := strconv.Atoi(r.PathValue("lineID"))

	if err := models.OrderLineDelete(h.DB, lineID, orderID); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Return updated order detail
	order, err := models.OrderGetByID(h.DB, orderID)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	h.renderPartial(w, "orders/detail.html", "order-lines", order)
}
