// Report endpoint — serves HTML reports.
// Mirrors: odoo/addons/web/controllers/report.py ReportController
package server

import (
	"fmt"
	"html/template"
	"net/http"
	"strconv"
	"strings"

	"odoo-go/pkg/orm"
)

// handleReport serves HTML reports.
// Route: /report/html/<report_name>/<ids>
// Mirrors: odoo/addons/web/controllers/report.py report_routes()
func (s *Server) handleReport(w http.ResponseWriter, r *http.Request) {
	// Parse URL: /report/html/account.report_invoice/1,2,3
	parts := strings.Split(strings.TrimPrefix(r.URL.Path, "/"), "/")
	// Expected: ["report", "html", "<report_name>", "<ids>"]
	if len(parts) < 4 {
		http.Error(w, "Invalid report URL. Expected: /report/html/<report_name>/<ids>", http.StatusBadRequest)
		return
	}

	reportName := parts[2]
	idsStr := parts[3]

	// Parse record IDs
	var ids []int64
	for _, s := range strings.Split(idsStr, ",") {
		s = strings.TrimSpace(s)
		if s == "" {
			continue
		}
		id, err := strconv.ParseInt(s, 10, 64)
		if err != nil {
			http.Error(w, fmt.Sprintf("Invalid ID %q: %v", s, err), http.StatusBadRequest)
			return
		}
		ids = append(ids, id)
	}

	if len(ids) == 0 {
		http.Error(w, "No record IDs provided", http.StatusBadRequest)
		return
	}

	// Get session
	uid := int64(1)
	companyID := int64(1)
	if sess := GetSession(r); sess != nil {
		uid = sess.UID
		companyID = sess.CompanyID
	}

	env, err := orm.NewEnvironment(r.Context(), orm.EnvConfig{
		Pool: s.pool, UID: uid, CompanyID: companyID,
	})
	if err != nil {
		http.Error(w, "Internal error", http.StatusInternalServerError)
		return
	}
	defer env.Close()

	// Determine model from report name
	modelName := resolveReportModel(reportName)
	if modelName == "" {
		http.Error(w, "Unknown report: "+reportName, http.StatusNotFound)
		return
	}

	// Read records
	rs := env.Model(modelName).Browse(ids...)
	records, err := rs.Read(nil)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	if err := env.Commit(); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Render HTML report
	html := renderHTMLReport(reportName, modelName, records)
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	w.Write([]byte(html))
}

// resolveReportModel maps a report name to the ORM model it operates on.
// Mirrors: odoo ir.actions.report → model field.
func resolveReportModel(reportName string) string {
	mapping := map[string]string{
		"account.report_invoice":         "account.move",
		"sale.report_saleorder":          "sale.order",
		"stock.report_picking":           "stock.picking",
		"purchase.report_purchaseorder":  "purchase.order",
		"contacts.report_partner":        "res.partner",
	}
	return mapping[reportName]
}

// renderHTMLReport generates a basic HTML report for the given records.
// This is a minimal implementation — Odoo uses QWeb templates for real reports.
func renderHTMLReport(reportName, modelName string, records []orm.Values) string {
	var b strings.Builder
	b.WriteString(`<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Report: `)
	b.WriteString(htmlEscape(reportName))
	b.WriteString(`</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
table { width: 100%; border-collapse: collapse; margin: 20px 0; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background: #f5f5f5; font-weight: bold; }
h1 { color: #333; }
h2 { color: #555; margin-top: 30px; }
.header { border-bottom: 2px solid #875A7B; padding-bottom: 10px; margin-bottom: 20px; }
.report-info { color: #888; font-size: 0.9em; margin-bottom: 30px; }
.record-section { page-break-after: always; margin-bottom: 40px; }
.record-section:last-child { page-break-after: avoid; }
@media print {
  body { margin: 20px; }
  .no-print { display: none; }
}
</style>
</head>
<body>
<div class="header">
  <h1>`)
	b.WriteString(htmlEscape(reportName))
	b.WriteString(`</h1>
  <div class="report-info">Model: `)
	b.WriteString(htmlEscape(modelName))
	b.WriteString(fmt.Sprintf(` | Records: %d`, len(records)))
	b.WriteString(`</div>
</div>
<div class="no-print">
  <button onclick="window.print()">Print</button>
</div>
`)

	for _, rec := range records {
		b.WriteString(`<div class="record-section">`)

		// Use "name" or "display_name" as section title if available
		title := ""
		if v, ok := rec["display_name"]; ok {
			title = fmt.Sprintf("%v", v)
		} else if v, ok := rec["name"]; ok {
			title = fmt.Sprintf("%v", v)
		}
		if title != "" {
			b.WriteString(fmt.Sprintf("<h2>%s</h2>", htmlEscape(title)))
		}

		b.WriteString("<table>")
		b.WriteString("<tr><th>Field</th><th>Value</th></tr>")
		for key, val := range rec {
			if key == "id" {
				continue
			}
			valStr := fmt.Sprintf("%v", val)
			if valStr == "<nil>" {
				valStr = ""
			}
			b.WriteString(fmt.Sprintf("<tr><td>%s</td><td>%s</td></tr>",
				htmlEscape(key), htmlEscape(valStr)))
		}
		b.WriteString("</table>")
		b.WriteString("</div>")
	}

	b.WriteString("</body></html>")
	return b.String()
}

// htmlEscape escapes HTML special characters.
func htmlEscape(s string) string {
	return template.HTMLEscapeString(s)
}
