package routes

import (
	"database/sql"
	"encoding/json"
	"net/http"
	"strings"

	"github.com/lib/pq"
)

type ProductSizeMatchRule struct {
	ProductGroupID int      `json:"product_group_id"`
	Kategori       string   `json:"kategori"`
	UrunAnaGrubu   string   `json:"urun_ana_grubu"`
	UrunAltGrubu   string   `json:"urun_alt_grubu"`
	GroupKeys      []string `json:"group_keys"`
}

type ProductSizeMatchResponse struct {
	Rules   []ProductSizeMatchRule `json:"rules"`
	Schemas map[string][]string    `json:"schemas"`
}

func fallbackTakSchema() map[string][]string {
	return map[string][]string{
		"tak": {"44", "46", "48", "50", "52", "54", "56", "58", "60", "62", "64", "66", "68", "70", "72", "74"},
	}
}

func parseSizeValuesCSV(raw string) []string {
	parts := strings.Split(raw, ",")
	out := make([]string, 0, len(parts))
	seen := map[string]struct{}{}
	for _, p := range parts {
		v := strings.TrimSpace(p)
		if v == "" {
			v = " "
		}
		if _, ok := seen[v]; ok {
			continue
		}
		seen[v] = struct{}{}
		out = append(out, v)
	}
	return out
}

func loadSizeSchemas(pgDB *sql.DB) (map[string][]string, error) {
	rows, err := pgDB.Query(`
		SELECT
			COALESCE(group_key, ''),
			COALESCE(size_values, '')
		FROM mk_size_group
	`)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	schemas := map[string][]string{}
	for rows.Next() {
		var groupKey string
		var sizeValues string
		if err := rows.Scan(&groupKey, &sizeValues); err != nil {
			return nil, err
		}
		key := strings.TrimSpace(groupKey)
		if key == "" {
			continue
		}
		schemas[key] = parseSizeValuesCSV(sizeValues)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}

	if len(schemas) == 0 {
		schemas = fallbackTakSchema()
	}
	if _, ok := schemas["tak"]; !ok {
		schemas["tak"] = fallbackTakSchema()["tak"]
	}

	return schemas, nil
}

func loadProductSizeMatchData(pgDB *sql.DB) (*ProductSizeMatchResponse, error) {
	rows, err := pgDB.Query(`
			SELECT
				pg.id AS product_group_id,
				COALESCE(pg.kategori, ''),
				COALESCE(pg.urun_ana_grubu, ''),
				COALESCE(pg.urun_alt_grubu, ''),
				COALESCE(
					array_agg(DISTINCT sm.size_group_key ORDER BY sm.size_group_key)
						FILTER (WHERE sm.size_group_key IS NOT NULL),
					ARRAY[]::text[]
				) AS group_keys
			FROM mk_product_size_match sm
			JOIN mk_product_group pg
				ON pg.id = sm.product_group_id
			GROUP BY
				pg.id, pg.kategori, pg.urun_ana_grubu, pg.urun_alt_grubu
			ORDER BY pg.id
		`)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	schemas, err := loadSizeSchemas(pgDB)
	if err != nil {
		schemas = fallbackTakSchema()
	}
	resp := &ProductSizeMatchResponse{
		Rules:   make([]ProductSizeMatchRule, 0),
		Schemas: schemas,
	}

	for rows.Next() {
		var item ProductSizeMatchRule
		var arr pq.StringArray
		if err := rows.Scan(
			&item.ProductGroupID,
			&item.Kategori,
			&item.UrunAnaGrubu,
			&item.UrunAltGrubu,
			&arr,
		); err != nil {
			return nil, err
		}
		item.GroupKeys = make([]string, 0, len(arr))
		for _, g := range arr {
			g = strings.TrimSpace(g)
			if g == "" {
				continue
			}
			item.GroupKeys = append(item.GroupKeys, g)
		}
		resp.Rules = append(resp.Rules, item)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}

	return resp, nil
}

// GET /api/product-size-match/rules
func GetProductSizeMatchRulesHandler(pgDB *sql.DB) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		resp, err := loadProductSizeMatchData(pgDB)
		if err != nil {
			http.Error(w, "product-size-match load failed: "+err.Error(), http.StatusInternalServerError)
			return
		}
		w.Header().Set("Content-Type", "application/json; charset=utf-8")
		_ = json.NewEncoder(w).Encode(resp)
	})
}
