package com.correx.apps.server.personalization

import com.correx.core.config.OperatorProfile
import com.correx.core.config.ProfileLoader
import com.correx.core.events.types.SessionId
import com.correx.core.journal.DefaultDecisionJournalRepository
import com.correx.core.journal.model.DecisionKind
import org.slf4j.LoggerFactory
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardOpenOption

class ProfileAdaptationService(
    private val decisionJournalRepository: DefaultDecisionJournalRepository,
    private val summarize: suspend (String) -> String,
    private val proposedPath: Path = ProfileLoader.profilePath().resolveSibling("profile.proposed.toml"),
) {
    private val log = LoggerFactory.getLogger(ProfileAdaptationService::class.java)

    suspend fun proposeAdaptation(sessionId: SessionId, currentProfile: OperatorProfile) {
        val journal = decisionJournalRepository.getJournal(sessionId)
        val relevantKinds = setOf(
            DecisionKind.STEERING,
            DecisionKind.PREEMPT,
            DecisionKind.FAILURE,
            DecisionKind.APPROVAL,
        )
        val relevantRecords = journal.records.filter { it.kind in relevantKinds }

        if (relevantRecords.isEmpty()) return

        val prompt = buildString {
            appendLine("You are analysing an operator's session to propose updates to their correx profile.")
            appendLine("Current profile `about`:")
            appendLine(currentProfile.about.ifBlank { "(empty)" })
            appendLine()
            appendLine(
                "Current preferences: approval_mode=${currentProfile.preferences.approvalMode}, " +
                    "conventions=${currentProfile.preferences.conventions}",
            )
            appendLine()
            appendLine("Session decisions that reveal operator preferences (steering, corrections, failures):")
            relevantRecords.forEach { appendLine("- [${it.kind}] ${it.summary}") }
            appendLine()
            appendLine(
                "Propose a concise update to the profile as a TOML snippet. " +
                    "Only include fields that should change. If nothing should change, respond with: # no changes",
            )
        }

        val proposed = runCatching { summarize(prompt) }.getOrElse {
            log.warn("Profile adaptation summarization failed: {}", it.message)
            return
        }

        if (proposed.trimStart().startsWith("# no changes")) return

        runCatching {
            Files.writeString(proposedPath, proposed, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)
            log.info("Profile adaptation proposed — review and merge: {}", proposedPath)
        }.onFailure { log.warn("Could not write proposed profile: {}", it.message) }
    }
}
