//
//  DataControllerDELETE.swift
//  Reflect
//
//  SwiftData DELETE operations.
//

import SwiftData
import Foundation
import os.log

extension DataController {

    // MARK: - Photo Cleanup

    func cleanupPhotoIfNeeded(for entry: MoodEntryModel) {
        if let photoID = entry.photoID {
            if !PhotoManager.shared.deletePhoto(id: photoID) {
                AppLogger.general.warning("Failed to delete orphaned photo \(photoID.uuidString) for entry on \(entry.forDate)")
            }
        }
    }

    // MARK: - Delete Operations

    func clearDB() {
        do {
            // Clean up photo files before batch delete
            let descriptor = FetchDescriptor<MoodEntryModel>()
            if let allEntries = try? modelContext.fetch(descriptor) {
                for entry in allEntries {
                    cleanupPhotoIfNeeded(for: entry)
                }
            }

            try modelContext.delete(model: MoodEntryModel.self)
            saveAndRunDataListeners()
            AnalyticsManager.shared.track(.allDataCleared)
        } catch {
            AppLogger.general.error("Failed to clear database: \(error.localizedDescription)")
        }
    }

    func deleteLast(numberOfEntries: Int) {
        guard let startDate = Calendar.current.date(byAdding: .day, value: -numberOfEntries, to: Date()) else { return }
        let entries = getData(startDate: startDate, endDate: Date(), includedDays: [])

        for entry in entries {
            cleanupPhotoIfNeeded(for: entry)
            modelContext.delete(entry)
        }
        saveAndRunDataListeners()
    }

    func deleteRandomFromLast(numberOfEntries: Int) {
        guard let startDate = Calendar.current.date(byAdding: .day, value: -numberOfEntries, to: Date()) else { return }
        let entries = getData(startDate: startDate, endDate: Date(), includedDays: [])

        for entry in entries where Bool.random() {
            cleanupPhotoIfNeeded(for: entry)
            modelContext.delete(entry)
        }
        saveAndRunDataListeners()
    }

    /// Get ALL entries for a specific date (not just the first one)
    func getAllEntries(byDate date: Date) -> [MoodEntryModel] {
        let startDate = Calendar.current.startOfDay(for: date)
        let endDate = Calendar.current.date(byAdding: .day, value: 1, to: startDate)!

        let descriptor = FetchDescriptor<MoodEntryModel>(
            predicate: #Predicate { entry in
                entry.forDate >= startDate && entry.forDate < endDate
            },
            sortBy: [SortDescriptor(\.forDate, order: .forward)]
        )

        return (try? modelContext.fetch(descriptor)) ?? []
    }

    /// Delete ALL entries for a specific date
    func deleteAllEntries(forDate date: Date) {
        let entries = getAllEntries(byDate: date)
        for entry in entries {
            cleanupPhotoIfNeeded(for: entry)
            modelContext.delete(entry)
        }
        saveAndRunDataListeners()
    }

    /// Find and remove duplicate entries, keeping only the most recent for each date
    /// Returns the number of duplicates removed
    @discardableResult
    func removeDuplicates() -> Int {
        let allEntries = getData(startDate: Date(timeIntervalSince1970: 0), endDate: Date(), includedDays: [])

        // Group by day
        var entriesByDay = [Date: [MoodEntryModel]]()
        let calendar = Calendar.current

        for entry in allEntries {
            let dayStart = calendar.startOfDay(for: entry.forDate)
            entriesByDay[dayStart, default: []].append(entry)
        }

        var duplicatesRemoved = 0

        for (_, dayEntries) in entriesByDay where dayEntries.count > 1 {
            // Sort by timestamp (most recent first), preferring non-missing moods
            let sorted = dayEntries.sorted { a, b in
                // Prefer non-missing moods
                if a.mood != .missing && b.mood == .missing { return true }
                if a.mood == .missing && b.mood != .missing { return false }
                // Then by timestamp (most recent first)
                return a.timestamp > b.timestamp
            }

            // Keep the first (best) entry, delete the rest
            for entry in sorted.dropFirst() {
                cleanupPhotoIfNeeded(for: entry)
                modelContext.delete(entry)
                duplicatesRemoved += 1
            }
        }

        if duplicatesRemoved > 0 {
            saveAndRunDataListeners()
            AppLogger.general.info("Removed \(duplicatesRemoved) duplicate entries")
            AnalyticsManager.shared.track(.duplicatesRemoved(count: duplicatesRemoved))
        }

        return duplicatesRemoved
    }
}
