package mail

import (
	"context"

	"github.com/ultisuite/ulti-backend/internal/mail/sanitize"
)

const resanitizeBatchSize = 200

type ResanitizeBodiesResult struct {
	Scanned int `json:"scanned"`
	Updated int `json:"updated"`
}

// ResanitizeAccountBodies re-applies email HTML sanitization to stored messages.
func (s *Service) ResanitizeAccountBodies(ctx context.Context, externalID, accountID string) (ResanitizeBodiesResult, error) {
	if err := s.verifyAccountOwnership(ctx, externalID, accountID); err != nil {
		return ResanitizeBodiesResult{}, err
	}
	return s.ResanitizeAccountBodiesByID(ctx, accountID)
}

// ResanitizeAccountBodiesByID re-sanitizes messages without an ownership check (CLI/admin).
func (s *Service) ResanitizeAccountBodiesByID(ctx context.Context, accountID string) (ResanitizeBodiesResult, error) {
	var result ResanitizeBodiesResult
	var lastID string
	for {
		rows, err := s.db.Query(ctx, `
			SELECT id, body_html
			FROM messages
			WHERE account_id = $1
			  AND body_html <> ''
			  AND ($2 = '' OR id > $2::uuid)
			ORDER BY id
			LIMIT $3
		`, accountID, lastID, resanitizeBatchSize)
		if err != nil {
			return result, err
		}

		batchCount := 0
		for rows.Next() {
			var id, bodyHTML string
			if err := rows.Scan(&id, &bodyHTML); err != nil {
				rows.Close()
				return result, err
			}
			batchCount++
			result.Scanned++
			lastID = id

			sanitized := sanitize.SanitizeHTML(bodyHTML)
			if sanitized == bodyHTML {
				continue
			}
			if _, err := s.db.Exec(ctx, `
				UPDATE messages SET body_html = $2, updated_at = NOW() WHERE id = $1
			`, id, sanitized); err != nil {
				rows.Close()
				return result, err
			}
			result.Updated++
		}
		if err := rows.Err(); err != nil {
			return result, err
		}
		rows.Close()

		if batchCount < resanitizeBatchSize {
			break
		}
	}

	return result, nil
}
