package routes

import (
	"bssapp-backend/auth"
	"bssapp-backend/queries"
	"context"
	"database/sql"
	"encoding/json"
	"log"
	"net/http"
	"strings"
	"time"
)

type productPricingCalcRequest struct {
	ProductCodes   []string `json:"product_codes"`
	RateDate       string   `json:"rate_date"`
	ForceFxRefresh bool     `json:"force_fx_refresh"`
	PreviewOnly    bool     `json:"preview_only"`

	Search       string   `json:"q"`
	ProductCode  []string `json:"product_code"`
	BrandGroup   []string `json:"brand_group_selection"`
	AskiliYan    []string `json:"askili_yan"`
	Kategori     []string `json:"kategori"`
	UrunIlkGrubu []string `json:"urun_ilk_grubu"`
	UrunAnaGrubu []string `json:"urun_ana_grubu"`
	UrunAltGrubu []string `json:"urun_alt_grubu"`
	Icerik       []string `json:"icerik"`
	Karisim      []string `json:"karisim"`
	Marka        []string `json:"marka"`
}

func PostProductPricingCalculateSnapshotsHandler(pg *sql.DB) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		started := time.Now()
		traceID := buildPricingTraceID(r)
		w.Header().Set("X-Trace-ID", traceID)

		claims, ok := auth.GetClaimsFromContext(r.Context())
		if !ok || claims == nil {
			http.Error(w, "unauthorized", http.StatusUnauthorized)
			return
		}

		ctx, cancel := context.WithTimeout(r.Context(), 170*time.Second)
		defer cancel()

		reqBody := productPricingCalcRequest{}
		if r.Body != nil {
			_ = json.NewDecoder(r.Body).Decode(&reqBody)
		}

		filters := queries.ProductPricingFilters{
			Search:       strings.TrimSpace(reqBody.Search),
			ProductCode:  reqBody.ProductCode,
			BrandGroup:   reqBody.BrandGroup,
			AskiliYan:    reqBody.AskiliYan,
			Kategori:     reqBody.Kategori,
			UrunIlkGrubu: reqBody.UrunIlkGrubu,
			UrunAnaGrubu: reqBody.UrunAnaGrubu,
			UrunAltGrubu: reqBody.UrunAltGrubu,
			Icerik:       reqBody.Icerik,
			Karisim:      reqBody.Karisim,
			Marka:        reqBody.Marka,
		}
		if filters.Search == "" && len(filters.ProductCode) == 0 && len(filters.BrandGroup) == 0 &&
			len(filters.AskiliYan) == 0 && len(filters.Kategori) == 0 && len(filters.UrunIlkGrubu) == 0 &&
			len(filters.UrunAnaGrubu) == 0 && len(filters.UrunAltGrubu) == 0 && len(filters.Icerik) == 0 &&
			len(filters.Karisim) == 0 && len(filters.Marka) == 0 {
			filters = parseProductPricingFilters(r)
		}

		calcReq := queries.ProductPricingSnapshotCalcRequest{
			ProductCodes:   reqBody.ProductCodes,
			Filters:        filters,
			RateDate:       reqBody.RateDate,
			ForceFxRefresh: reqBody.ForceFxRefresh,
		}
		if reqBody.PreviewOnly {
			result, err := queries.PreviewProductPricingSnapshots(ctx, pg, calcReq)
			if err != nil {
				log.Printf("[ProductPricingCalcPreview] trace=%s user=%s id=%d err=%v duration_ms=%d",
					traceID, claims.Username, claims.ID, err, time.Since(started).Milliseconds())
				http.Error(w, "Urun fiyat hesap onizlemesi olusturulamadi: "+err.Error(), http.StatusInternalServerError)
				return
			}
			log.Printf("[ProductPricingCalcPreview] trace=%s user=%s id=%d requested=%d calculated=%d skipped=%d fx_date=%s duration_ms=%d",
				traceID, claims.Username, claims.ID, result.Requested, result.Calculated, result.Skipped, result.RateDate, time.Since(started).Milliseconds())
			w.Header().Set("Content-Type", "application/json; charset=utf-8")
			_ = json.NewEncoder(w).Encode(result)
			return
		}
		result, err := queries.CalculateProductPricingSnapshots(ctx, pg, calcReq)
		if err != nil {
			log.Printf("[ProductPricingCalc] trace=%s user=%s id=%d err=%v duration_ms=%d",
				traceID, claims.Username, claims.ID, err, time.Since(started).Milliseconds())
			http.Error(w, "Urun fiyat hesaplari olusturulamadi: "+err.Error(), http.StatusInternalServerError)
			return
		}

		log.Printf("[ProductPricingCalc] trace=%s user=%s id=%d requested=%d calculated=%d skipped=%d fx_date=%s duration_ms=%d",
			traceID, claims.Username, claims.ID, result.Requested, result.Calculated, result.Skipped, result.RateDate, time.Since(started).Milliseconds())
		w.Header().Set("Content-Type", "application/json; charset=utf-8")
		_ = json.NewEncoder(w).Encode(result)
	}
}
