package handlers

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

	"erp_system/internal/models"
)

func (h *Handler) ChartOfAccounts(w http.ResponseWriter, r *http.Request) {
	accounts, err := models.GLAccountGetAll(h.DB)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	data := map[string]interface{}{
		"Title":      "Chart of Accounts",
		"Username":   h.getUsername(r),
		"ActivePage": "ledger",
		"Accounts":   accounts,
	}
	h.render(w, []string{"layout.html", "ledger/chart_of_accounts.html"}, data)
}

func (h *Handler) JournalEntries(w http.ResponseWriter, r *http.Request) {
	entries, err := models.JournalEntryGetAll(h.DB)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	data := map[string]interface{}{
		"Title":      "Journal Entries",
		"Username":   h.getUsername(r),
		"ActivePage": "ledger",
		"Entries":    entries,
	}
	h.render(w, []string{"layout.html", "ledger/journal_entries.html"}, data)
}

func (h *Handler) JournalEntryNew(w http.ResponseWriter, r *http.Request) {
	accounts, _ := models.GLAccountGetAll(h.DB)

	data := map[string]interface{}{
		"Title":      "New Journal Entry",
		"Username":   h.getUsername(r),
		"ActivePage": "ledger",
		"Accounts":   accounts,
		"Today":      time.Now().Format("2006-01-02"),
	}
	h.render(w, []string{"layout.html", "ledger/journal_entry_form.html"}, data)
}

func (h *Handler) JournalEntryCreate(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()

	je := &models.JournalEntry{
		EntryDate:   r.FormValue("entry_date"),
		Description: r.FormValue("description"),
		Reference:   r.FormValue("reference"),
	}

	// Parse lines from form
	accountIDs := r.Form["account_id"]
	debits := r.Form["debit"]
	credits := r.Form["credit"]

	for i := range accountIDs {
		accID, _ := strconv.Atoi(accountIDs[i])
		debit, _ := strconv.ParseFloat(debits[i], 64)
		credit, _ := strconv.ParseFloat(credits[i], 64)

		if accID == 0 || (debit == 0 && credit == 0) {
			continue
		}

		je.Lines = append(je.Lines, models.JournalLine{
			AccountID: accID,
			Debit:     debit,
			Credit:    credit,
		})
	}

	if len(je.Lines) < 2 {
		accounts, _ := models.GLAccountGetAll(h.DB)
		data := map[string]interface{}{
			"Title":      "New Journal Entry",
			"Username":   h.getUsername(r),
			"ActivePage": "ledger",
			"Accounts":   accounts,
			"Today":      time.Now().Format("2006-01-02"),
			"Error":      "At least two lines are required",
		}
		h.render(w, []string{"layout.html", "ledger/journal_entry_form.html"}, data)
		return
	}

	if err := models.JournalEntryInsert(h.DB, je); err != nil {
		accounts, _ := models.GLAccountGetAll(h.DB)
		data := map[string]interface{}{
			"Title":      "New Journal Entry",
			"Username":   h.getUsername(r),
			"ActivePage": "ledger",
			"Accounts":   accounts,
			"Today":      time.Now().Format("2006-01-02"),
			"Error":      err.Error(),
		}
		h.render(w, []string{"layout.html", "ledger/journal_entry_form.html"}, data)
		return
	}

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

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

	data := map[string]interface{}{
		"Title":      "Journal Entry #" + strconv.Itoa(id),
		"Username":   h.getUsername(r),
		"ActivePage": "ledger",
		"Entry":      entry,
	}
	h.render(w, []string{"layout.html", "ledger/journal_entry_detail.html"}, data)
}

func (h *Handler) TrialBalance(w http.ResponseWriter, r *http.Request) {
	rows, err := models.GetTrialBalance(h.DB)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	var totalDebit, totalCredit float64
	for _, row := range rows {
		totalDebit += row.Debit
		totalCredit += row.Credit
	}

	data := map[string]interface{}{
		"Title":       "Trial Balance",
		"Username":    h.getUsername(r),
		"ActivePage":  "ledger",
		"Rows":        rows,
		"TotalDebit":  totalDebit,
		"TotalCredit": totalCredit,
	}
	h.render(w, []string{"layout.html", "ledger/trial_balance.html"}, data)
}
