// // GuidedReflection.swift // Reflect // // Codable model for guided reflection responses, stored as JSON in MoodEntryModel. // import Foundation // MARK: - Mood Category enum MoodCategory: String, Codable { case positive // great, good → 3 questions (Behavioral Activation) case neutral // average → 4 questions (ACT Cognitive Defusion) case negative // bad, horrible → 4 questions (CBT Thought Record) init(from mood: Mood) { switch mood { case .great, .good: self = .positive case .average: self = .neutral case .horrible, .bad: self = .negative default: self = .neutral } } var questionCount: Int { switch self { case .positive: return 3 case .neutral, .negative: return 4 } } /// The therapeutic technique name for display purposes. var techniqueName: String { switch self { case .positive: return "Behavioral Activation" case .neutral: return "Acceptance & Commitment Therapy" case .negative: return "Cognitive Behavioral Therapy" } } /// Short CBT step labels shown above each question. var stepLabels: [String] { switch self { case .negative: return [ String(localized: "Situation"), String(localized: "Automatic Thought"), String(localized: "Perspective Check"), String(localized: "Reframe"), ] case .neutral: return [ String(localized: "Awareness"), String(localized: "Thought"), String(localized: "Defusion"), String(localized: "Values"), ] case .positive: return [ String(localized: "Activity"), String(localized: "Awareness"), String(localized: "Planning"), ] } } } // MARK: - Guided Reflection struct GuidedReflection: Codable, Equatable { struct Response: Codable, Equatable, Identifiable { var id: Int // question index (0-based) let question: String var answer: String } let moodCategory: MoodCategory var responses: [Response] var completedAt: Date? // MARK: - Computed Properties var isComplete: Bool { responses.count == moodCategory.questionCount && responses.allSatisfy { !$0.answer.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty } } var answeredCount: Int { responses.filter { !$0.answer.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty }.count } var totalQuestions: Int { moodCategory.questionCount } // MARK: - Factory static func createNew(for mood: Mood) -> GuidedReflection { let category = MoodCategory(from: mood) let questionTexts = questions(for: category) let responses = questionTexts.enumerated().map { index, question in Response(id: index, question: question, answer: "") } return GuidedReflection(moodCategory: category, responses: responses, completedAt: nil) } static func questions(for category: MoodCategory) -> [String] { switch category { case .positive: return [ String(localized: "guided_reflection_positive_q1"), String(localized: "guided_reflection_positive_q2"), String(localized: "guided_reflection_positive_q3"), ] case .neutral: return [ String(localized: "guided_reflection_neutral_q1"), String(localized: "guided_reflection_neutral_q2"), String(localized: "guided_reflection_neutral_q3"), String(localized: "guided_reflection_neutral_q4"), ] case .negative: return [ String(localized: "guided_reflection_negative_q1"), String(localized: "guided_reflection_negative_q2"), String(localized: "guided_reflection_negative_q3"), String(localized: "guided_reflection_negative_q4"), ] } } // MARK: - JSON Helpers func encode() -> String? { guard let data = try? JSONEncoder().encode(self) else { return nil } return String(data: data, encoding: .utf8) } static func decode(from json: String) -> GuidedReflection? { guard let data = json.data(using: .utf8) else { return nil } return try? JSONDecoder().decode(GuidedReflection.self, from: data) } }