package api

import (
	"net/http"
	"strings"
	"time"

	"archivmail/internal/userstore"
	"archivmail/pkg/mailparser"
)

// handleGetThread returns all mails in a thread, ordered by date ascending.
// Access is tenant-isolated identical to handleGetMail.
//
// GET /api/mail/thread/{threadID}
func (s *Server) handleGetThread(w http.ResponseWriter, r *http.Request) {
	threadID := r.PathValue("threadID")
	if threadID == "" {
		writeError(w, http.StatusBadRequest, "missing thread id")
		return
	}

	sess := sessionFromCtx(r.Context())
	tenantID := tenantFromCtx(r.Context())

	// domain_auditor without tenant → deny
	if sess.Role == userstore.RoleDomainAuditor && tenantID == nil {
		writeError(w, http.StatusForbidden, "access denied")
		return
	}

	// For user role, we still filter per mail below
	ids, err := s.store.GetMailsByThread(r.Context(), threadID, tenantID)
	if err != nil {
		writeError(w, http.StatusInternalServerError, "thread lookup failed")
		return
	}

	// PROJ-55: a global auditor (no tenant_id) may only see mails without a
	// tenant assignment. A tenant-scoped auditor (tenant_id set) is already
	// constrained by GetMailsByThread's tenant filter above.
	var auditorAllowed map[string]struct{}
	if auditorIsGlobal(sess) {
		noTenant, idErr := s.store.GetAllIDsWithoutTenant(r.Context())
		if idErr != nil {
			writeError(w, http.StatusInternalServerError, "access check failed")
			return
		}
		auditorAllowed = make(map[string]struct{}, len(noTenant))
		for _, nid := range noTenant {
			auditorAllowed[nid] = struct{}{}
		}
	}

	type mailSummary struct {
		ID      string `json:"id"`
		From    string `json:"from,omitempty"`
		To      string `json:"to,omitempty"`
		Subject string `json:"subject"`
		Date    string `json:"date,omitempty"`
		Size    int    `json:"size"`
	}

	mails := make([]mailSummary, 0, len(ids))
	for _, id := range ids {
		raw, err := s.store.Load(id)
		if err != nil {
			continue
		}
		pm, err := mailparser.Parse(raw)
		if err != nil {
			continue
		}

		// user isolation
		if sess.Role == userstore.RoleUser {
			if sess.Email == "" || !mailBelongsToUser(pm, strings.ToLower(sess.Email)) {
				continue
			}
		}

		// global auditor isolation: skip mails that belong to a tenant.
		if auditorAllowed != nil {
			if _, ok := auditorAllowed[id]; !ok {
				continue
			}
		}

		var dateStr string
		if !pm.Date.IsZero() {
			dateStr = pm.Date.UTC().Format(time.RFC3339)
		}

		mails = append(mails, mailSummary{
			ID:      id,
			From:    pm.From,
			To:      strings.Join(pm.To, ", "),
			Subject: pm.Subject,
			Date:    dateStr,
			Size:    len(raw),
		})
	}

	writeJSON(w, http.StatusOK, map[string]interface{}{
		"thread_id": threadID,
		"total":     len(mails),
		"mails":     mails,
	})
}
