// // SharingScreenshotExporter.swift // Reflect // // Debug utility to export sharing template screenshots. // #if DEBUG import SwiftUI import UIKit import os.log /// Exports sharing template screenshots for App Store marketing @MainActor class SharingScreenshotExporter { /// Exports all original templates + kept variations as PNGs /// - Returns: URL to the export directory, or nil if failed static func exportAllSharingScreenshots() async -> URL? { let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let exportPath = documentsPath.appendingPathComponent("SharingExports", isDirectory: true) // Clean and create export directory try? FileManager.default.removeItem(at: exportPath) do { try FileManager.default.createDirectory(at: exportPath, withIntermediateDirectories: true) } catch { AppLogger.export.error("Failed to create sharing export directory: \(error)") return nil } // Create subdirectories let origDir = exportPath.appendingPathComponent("originals", isDirectory: true) let varDir = exportPath.appendingPathComponent("variations", isDirectory: true) do { try FileManager.default.createDirectory(at: origDir, withIntermediateDirectories: true) try FileManager.default.createDirectory(at: varDir, withIntermediateDirectories: true) } catch { AppLogger.export.error("Failed to create sharing subdirectories: \(error)") return nil } var totalExported = 0 let distantPast = Date(timeIntervalSince1970: 0) let now = Date() let calendar = Calendar.current // ────────────────────────────────────────────── // Fetch shared data once for all variations // ────────────────────────────────────────────── // All moods data let allEntries = DataController.shared.getData( startDate: distantPast, endDate: now, includedDays: [1,2,3,4,5,6,7] ) let allMetrics = Random.createTotalPerc(fromEntries: allEntries) .sorted(by: { $0.mood.rawValue > $1.mood.rawValue }) // Current streak data (last 10 days) — fetch 12 days to handle boundary, take last 10 let streakFetchStart = calendar.date(byAdding: .day, value: -12, to: now)! let streakEntries = Array(DataController.shared.getData( startDate: streakFetchStart, endDate: now, includedDays: [1,2,3,4,5,6,7] ).suffix(10)) // Current month data let currentMonthEntries = DataController.shared.getData( startDate: now.startOfMonth, endDate: now.endOfMonth, includedDays: [1,2,3,4,5,6,7] ) let currentMonthMetrics = Random.createTotalPerc(fromEntries: currentMonthEntries) .sorted(by: { $0.mood.rawValue > $1.mood.rawValue }) let currentMonth = calendar.component(.month, from: now) // Last month data let lastMonthDate = calendar.date(byAdding: .month, value: -1, to: now)! let lastMonthStart = lastMonthDate.startOfMonth let lastMonthEnd = lastMonthDate.endOfMonth let lastMonthEntries = DataController.shared.getData( startDate: lastMonthStart, endDate: lastMonthEnd, includedDays: [1,2,3,4,5,6,7] ) let lastMonthMetrics = Random.createTotalPerc(fromEntries: lastMonthEntries) .sorted(by: { $0.mood.rawValue > $1.mood.rawValue }) let lastMonth = calendar.component(.month, from: lastMonthDate) // Longest streak data (find longest "great" streak) let selectedMood: Mood = .great let longestStreakEntries: [MoodEntryModel] = { var splitArrays = [[MoodEntryModel]]() var currentSplit = [MoodEntryModel]() for entry in allEntries { if entry.mood == selectedMood { currentSplit.append(entry) } else { splitArrays.append(currentSplit) currentSplit.removeAll() } } splitArrays.append(currentSplit) return splitArrays.sorted(by: { $0.count > $1.count }).first ?? [] }() // ────────────────────────────────────────────── // Export originals // ────────────────────────────────────────────── let allMoods = AllMoodsTotalTemplate(isPreview: false, startDate: distantPast, endDate: now, fakeData: false) if saveImage(allMoods.image, to: origDir, name: "all_moods_total") { totalExported += 1 } let currentStreak = CurrentStreakTemplate(isPreview: false, startDate: streakFetchStart, endDate: now, fakeData: false) if saveImage(currentStreak.image, to: origDir, name: "current_streak") { totalExported += 1 } let monthTotal = MonthTotalTemplate(isPreview: false, startDate: now.startOfMonth, endDate: now.endOfMonth, fakeData: false) if saveImage(monthTotal.image, to: origDir, name: "month_total") { totalExported += 1 } let longestStreak = LongestStreakTemplate(isPreview: false, startDate: distantPast, endDate: now, fakeData: false) if saveImage(longestStreak.image, to: origDir, name: "longest_streak") { totalExported += 1 } // ────────────────────────────────────────────── // Export All Moods variations (666x1190) // Kept: V2, V5 // ────────────────────────────────────────────── if saveImage(AllMoodsV2(metrics: allMetrics, totalCount: allEntries.count).image, to: varDir, name: "all_moods_v2_gradient") { totalExported += 1 } if saveImage(AllMoodsV5(metrics: allMetrics, totalCount: allEntries.count).image, to: varDir, name: "all_moods_v5_colorblock") { totalExported += 1 } // ────────────────────────────────────────────── // Export Current Streak variations (666x1190) // Kept: V2, V5 // ────────────────────────────────────────────── if saveImage(CurrentStreakV2(moodEntries: streakEntries).image, to: varDir, name: "current_streak_v2_gradient") { totalExported += 1 } if saveImage(CurrentStreakV5(moodEntries: streakEntries).image, to: varDir, name: "current_streak_v5_colorblock") { totalExported += 1 } // ────────────────────────────────────────────── // Export Month Total variations (666x1190) // Kept: V1, V5 — exported for BOTH current and last month // ────────────────────────────────────────────── // Current month if saveImage(MonthTotalV1(moodMetrics: currentMonthMetrics, moodEntries: currentMonthEntries, month: currentMonth).image, to: varDir, name: "month_total_v1_clean_current") { totalExported += 1 } if saveImage(MonthTotalV5(moodMetrics: currentMonthMetrics, moodEntries: currentMonthEntries, month: currentMonth).image, to: varDir, name: "month_total_v5_colorblock_current") { totalExported += 1 } // Last month if saveImage(MonthTotalV1(moodMetrics: lastMonthMetrics, moodEntries: lastMonthEntries, month: lastMonth).image, to: varDir, name: "month_total_v1_clean_lastmonth") { totalExported += 1 } if saveImage(MonthTotalV5(moodMetrics: lastMonthMetrics, moodEntries: lastMonthEntries, month: lastMonth).image, to: varDir, name: "month_total_v5_colorblock_lastmonth") { totalExported += 1 } // ────────────────────────────────────────────── // Export Longest Streak variations (650x400) // Kept: V2, V3 // ────────────────────────────────────────────── if saveImage(LongestStreakV2(streakEntries: longestStreakEntries, selectedMood: selectedMood).image, to: varDir, name: "longest_streak_v2_gradient") { totalExported += 1 } if saveImage(LongestStreakV3(streakEntries: longestStreakEntries, selectedMood: selectedMood).image, to: varDir, name: "longest_streak_v3_dark") { totalExported += 1 } print("📸 Total \(totalExported) sharing screenshots exported to: \(exportPath.path)") print(" originals/ — 4 original templates") print(" variations/ — 12 design variations (2 all moods, 2 current streak, 4 month total, 2 longest streak)") return exportPath } private static func saveImage(_ image: UIImage, to folder: URL, name: String) -> Bool { let url = folder.appendingPathComponent("\(name).png") if let data = image.pngData() { do { try data.write(to: url) return true } catch { AppLogger.export.error("Failed to save sharing screenshot '\(name)': \(error)") } } return false } } #endif