package export

// entities.go — v0.34.0 CS0
//
// Per-entity sanitization: strips sensitive, instance-specific, or
// non-portable fields before writing to the export archive. Each
// Sanitize* function returns a clean map ready for JSON marshalling.

import (
	"chat-switchboard/models"
)

// ── User ─────────────────────────────────────

// SanitizeUser strips password_hash (json:"-" already), vault fields,
// and external_id. The User struct's json tags already exclude
// password_hash, so standard marshalling is safe. We nil out a few
// more fields for cross-instance portability.
func SanitizeUser(u *models.User) *models.User {
	out := *u // shallow copy
	out.PasswordHash = ""
	out.ExternalID = nil
	return &out
}

// ── Channel ──────────────────────────────────

// ExportChannel is a Channel without instance-specific provider binding.
type ExportChannel struct {
	models.Channel
	ProviderConfigID *string `json:"provider_config_id,omitempty"` // always nil in export
}

// SanitizeChannel strips provider_config_id.
func SanitizeChannel(ch *models.Channel) ExportChannel {
	return ExportChannel{
		Channel:          *ch,
		ProviderConfigID: nil,
	}
}

// SanitizeChannels batch-sanitizes a slice.
func SanitizeChannels(chs []models.Channel) []ExportChannel {
	out := make([]ExportChannel, len(chs))
	for i := range chs {
		chs[i].ProviderConfigID = nil
		out[i] = SanitizeChannel(&chs[i])
	}
	return out
}

// ── Message ──────────────────────────────────

// ExportMessage is a Message without provider_config_id.
type ExportMessage struct {
	models.Message
	ProviderConfigID *string `json:"provider_config_id,omitempty"` // always nil
}

// SanitizeMessages strips provider_config_id from each message.
func SanitizeMessages(msgs []models.Message) []ExportMessage {
	out := make([]ExportMessage, len(msgs))
	for i := range msgs {
		msgs[i].ProviderConfigID = nil
		out[i] = ExportMessage{Message: msgs[i]}
	}
	return out
}

// ── Channel Model ────────────────────────────

// ExportChannelModel strips provider_config_id and persona_id.
type ExportChannelModel struct {
	ID           string `json:"id"`
	ChannelID    string `json:"channel_id"`
	ModelID      string `json:"model_id"`
	Handle       string `json:"handle,omitempty"`
	DisplayName  string `json:"display_name,omitempty"`
	SystemPrompt string `json:"system_prompt,omitempty"`
	IsDefault    bool   `json:"is_default"`
}

// SanitizeChannelModels strips instance-specific refs.
func SanitizeChannelModels(cms []models.ChannelModel) []ExportChannelModel {
	out := make([]ExportChannelModel, len(cms))
	for i, cm := range cms {
		out[i] = ExportChannelModel{
			ID:           cm.ID,
			ChannelID:    cm.ChannelID,
			ModelID:      cm.ModelID,
			Handle:       cm.Handle,
			DisplayName:  cm.DisplayName,
			SystemPrompt: cm.SystemPrompt,
			IsDefault:    cm.IsDefault,
		}
	}
	return out
}

// ── User Model Settings ──────────────────────

// ExportUserModelSetting strips provider_config_id.
type ExportUserModelSetting struct {
	models.UserModelSetting
	ProviderConfigID *string `json:"provider_config_id,omitempty"` // always nil
}

// SanitizeUserModelSettings strips instance-specific provider binding.
func SanitizeUserModelSettings(ums []models.UserModelSetting) []ExportUserModelSetting {
	out := make([]ExportUserModelSetting, len(ums))
	for i := range ums {
		ums[i].ProviderConfigID = nil
		out[i] = ExportUserModelSetting{UserModelSetting: ums[i]}
	}
	return out
}

// ── Usage Entry ──────────────────────────────

// ExportUsageEntry strips provider_config_id and routing_decision.
type ExportUsageEntry struct {
	ID                  string  `json:"id"`
	ChannelID           *string `json:"channel_id,omitempty"`
	UserID              string  `json:"user_id"`
	ModelID             string  `json:"model_id"`
	Role                *string `json:"role,omitempty"`
	PromptTokens        int     `json:"prompt_tokens"`
	CompletionTokens    int     `json:"completion_tokens"`
	CacheCreationTokens int     `json:"cache_creation_tokens"`
	CacheReadTokens     int     `json:"cache_read_tokens"`
	CostInput           *float64 `json:"cost_input,omitempty"`
	CostOutput          *float64 `json:"cost_output,omitempty"`
	CreatedAt           string  `json:"created_at"`
}

// SanitizeUsageEntries strips instance-specific fields.
func SanitizeUsageEntries(ues []models.UsageEntry) []ExportUsageEntry {
	out := make([]ExportUsageEntry, len(ues))
	for i, ue := range ues {
		out[i] = ExportUsageEntry{
			ID:                  ue.ID,
			ChannelID:           ue.ChannelID,
			UserID:              ue.UserID,
			ModelID:             ue.ModelID,
			Role:                ue.Role,
			PromptTokens:        ue.PromptTokens,
			CompletionTokens:    ue.CompletionTokens,
			CacheCreationTokens: ue.CacheCreationTokens,
			CacheReadTokens:     ue.CacheReadTokens,
			CostInput:           ue.CostInput,
			CostOutput:          ue.CostOutput,
			CreatedAt:           ue.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
		}
	}
	return out
}

// ── Workspace ────────────────────────────────

// ExportWorkspace strips root_path (json:"-" already) and git credentials.
type ExportWorkspace struct {
	models.Workspace
	GitCredentialID *string `json:"git_credential_id,omitempty"` // always nil
}

// SanitizeWorkspaces strips git credential refs.
func SanitizeWorkspaces(ws []models.Workspace) []ExportWorkspace {
	out := make([]ExportWorkspace, len(ws))
	for i := range ws {
		ws[i].GitCredentialID = nil
		ws[i].GitLastSync = nil
		out[i] = ExportWorkspace{Workspace: ws[i]}
	}
	return out
}

// ── Persona ──────────────────────────────────

// ExportPersona strips provider_config_id.
type ExportPersona struct {
	models.Persona
	ProviderConfigID *string `json:"provider_config_id,omitempty"` // always nil
}

// SanitizePersonas strips instance-specific provider binding.
func SanitizePersonas(ps []models.Persona) []ExportPersona {
	out := make([]ExportPersona, len(ps))
	for i := range ps {
		ps[i].ProviderConfigID = nil
		out[i] = ExportPersona{Persona: ps[i]}
	}
	return out
}

// ── Workflow ─────────────────────────────────

// SanitizeWorkflows strips webhook secrets.
func SanitizeWorkflows(wfs []models.Workflow) []models.Workflow {
	out := make([]models.Workflow, len(wfs))
	for i := range wfs {
		out[i] = wfs[i]
		out[i].WebhookSecret = ""
	}
	return out
}

// Note links use models.ExportNoteLink (includes source_note_id).
// See models/models.go for the type definition.

// Note, Memory, Folder, NotificationPreference,
// ChannelParticipant, ChannelCursor, Project, ProjectChannel,
// ProjectKB, ProjectNote, WorkspaceFile, PersonaGroup,
// PersonaGroupMember, KnowledgeBase, KBDocument, Group,
// GroupMember, ResourceGrant, Team, TeamMember, WorkflowVersion,
// WorkflowStage — these are exported as-is (no sensitive fields
// after query-level exclusion of embeddings).
