//
//  DataControllerHelper.swift
//  Reflect
//
//  SwiftData helper and test data operations.
//

import SwiftData
import Foundation

extension DataController {
    func randomEntries(count: Int) -> [MoodEntryModel] {
        var entries = [MoodEntryModel]()

        for idx in 0..<count {
            let date = Calendar.current.date(byAdding: .day, value: -idx, to: Date())!
            let entry = MoodEntryModel(
                forDate: date,
                mood: Mood.allValues.randomElement()!,
                entryType: .listView
            )
            entry.timestamp = date
            entries.append(entry)
        }
        return entries
    }

    func populateMemory() {
        #if DEBUG
        for idx in 1..<255 {
            let date = Calendar.current.date(byAdding: .day, value: -idx, to: Date())!
            var moodValue = Int.random(in: 2...4)
            if idx % 5 == 0 {
                moodValue = Int.random(in: 0...4)
            }

            let entry = MoodEntryModel(
                forDate: date,
                mood: Mood(rawValue: moodValue) ?? .average,
                entryType: .listView
            )
            entry.timestamp = date
            modelContext.insert(entry)
        }
        save()
        #endif
    }

    /// Creates an entry that is NOT inserted into the context - used for UI placeholders
    func generateObjectNotInArray(forDate date: Date = Date(), withMood mood: Mood = .placeholder) -> MoodEntryModel {
        let entry = MoodEntryModel(
            forDate: date,
            moodValue: mood.rawValue,
            entryType: EntryType.listView.rawValue,
            canEdit: false,
            canDelete: false
        )
        return entry
    }

    func populateTestData() {
        clearDB()

        for idx in 1..<1000 {
            let date = Calendar.current.date(byAdding: .day, value: -idx, to: Date())!
            var moodValue = Int.random(in: 3...4)
            if Int.random(in: 0...400) % 5 == 0 {
                moodValue = Int.random(in: 0...4)
            }

            let entry = MoodEntryModel(
                forDate: date,
                mood: Mood(rawValue: moodValue) ?? .average,
                entryType: .listView
            )
            modelContext.insert(entry)
        }

        saveAndRunDataListeners()
    }

    #if DEBUG
    func populate2YearsData() {
        clearDB()

        for idx in 1...730 {
            let date = Calendar.current.date(byAdding: .day, value: -idx, to: Date())!
            var moodValue = Int.random(in: 3...4)
            if Int.random(in: 0...400) % 5 == 0 {
                moodValue = Int.random(in: 0...4)
            }

            let entry = MoodEntryModel(
                forDate: date,
                mood: Mood(rawValue: moodValue) ?? .average,
                entryType: .listView
            )
            modelContext.insert(entry)
        }

        saveAndRunDataListeners()
    }
    #endif

    func longestStreak() -> [MoodEntryModel] {
        let descriptor = FetchDescriptor<MoodEntryModel>(
            sortBy: [SortDescriptor(\.forDate, order: .forward)]
        )
        return (try? modelContext.fetch(descriptor)) ?? []
    }
}
