package api

import (
	"encoding/json"
	"strings"
	"unicode/utf8"

	"github.com/gin-gonic/gin"
)

func orgReportListIncludeSummary(c *gin.Context) bool {
	inc := strings.ToLower(strings.TrimSpace(c.Query("include")))
	if inc == "" {
		return false
	}
	for _, part := range strings.Split(inc, ",") {
		if strings.TrimSpace(part) == "summary" {
			return true
		}
	}
	return false
}

func truncateRunes(s string, max int) string {
	s = strings.TrimSpace(s)
	if s == "" || max <= 0 {
		return ""
	}
	if utf8.RuneCountInString(s) <= max {
		return s
	}
	r := []rune(s)
	return string(r[:max])
}

// orgReportBodyListSummary extracts a thin preview from reports.body for superadmin list UIs.
// Aligns with FE workpulse.report.v1: task columns default to "todo" when unknown (see parseReportBody).
func orgReportBodyListSummary(body string) gin.H {
	z := gin.H{
		"taskCounts":        gin.H{"todo": 0, "doing": 0, "done": 0},
		"blockersPreview":   "",
		"workStart":         "",
		"workEnd":           "",
	}
	body = strings.TrimSpace(body)
	if body == "" || !strings.HasPrefix(body, "{") {
		return z
	}
	var root map[string]json.RawMessage
	if err := json.Unmarshal([]byte(body), &root); err != nil {
		return z
	}
	var schema string
	if raw, ok := root["schema"]; ok {
		_ = json.Unmarshal(raw, &schema)
	}
	if strings.TrimSpace(schema) != kanbanSchemaWorkpulseReportV1 {
		return z
	}
	var workStart, workEnd, workDescription, blockers, tomorrow string
	if raw, ok := root["workStart"]; ok {
		_ = json.Unmarshal(raw, &workStart)
	}
	if raw, ok := root["workEnd"]; ok {
		_ = json.Unmarshal(raw, &workEnd)
	}
	if raw, ok := root["workDescription"]; ok {
		_ = json.Unmarshal(raw, &workDescription)
	}
	if raw, ok := root["blockers"]; ok {
		_ = json.Unmarshal(raw, &blockers)
	}
	if raw, ok := root["tomorrow"]; ok {
		_ = json.Unmarshal(raw, &tomorrow)
	}
	z["workStart"] = strings.TrimSpace(workStart)
	z["workEnd"] = strings.TrimSpace(workEnd)
	descPreview := strings.TrimSpace(workDescription)
	if descPreview == "" {
		if b := strings.TrimSpace(blockers); b != "" {
			descPreview = b
		}
		if t := strings.TrimSpace(tomorrow); t != "" {
			if descPreview != "" {
				descPreview += "\n\n" + t
			} else {
				descPreview = t
			}
		}
	}
	z["blockersPreview"] = truncateRunes(descPreview, 120)

	todo, doing, done := 0, 0, 0
	if raw, ok := root["tasks"]; ok {
		var tasks []struct {
			ID     string `json:"id"`
			Title  string `json:"title"`
			Column string `json:"column"`
		}
		if err := json.Unmarshal(raw, &tasks); err == nil {
			for _, t := range tasks {
				if strings.TrimSpace(t.ID) == "" || strings.TrimSpace(t.Title) == "" {
					continue
				}
				switch strings.ToLower(strings.TrimSpace(t.Column)) {
				case "doing":
					doing++
				case "done":
					done++
				default:
					todo++
				}
			}
		}
	}
	z["taskCounts"] = gin.H{"todo": todo, "doing": doing, "done": done}
	return z
}
