//
//  AppShortcuts.swift
//  Reflect
//
//  App Intents and Siri Shortcuts for voice-activated mood logging
//

import AppIntents
import SwiftUI

// MARK: - Mood Entity for App Intents

struct MoodEntity: AppEntity {
    static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Mood")

    static var defaultQuery = MoodEntityQuery()

    var id: Int
    var name: String
    var mood: Mood

    var displayRepresentation: DisplayRepresentation {
        DisplayRepresentation(title: "\(name)")
    }

    static let allMoods: [MoodEntity] = [
        MoodEntity(id: 0, name: "Horrible", mood: .horrible),
        MoodEntity(id: 1, name: "Bad", mood: .bad),
        MoodEntity(id: 2, name: "Average", mood: .average),
        MoodEntity(id: 3, name: "Good", mood: .good),
        MoodEntity(id: 4, name: "Great", mood: .great)
    ]
}

struct MoodEntityQuery: EntityQuery {
    func entities(for identifiers: [Int]) async throws -> [MoodEntity] {
        MoodEntity.allMoods.filter { identifiers.contains($0.id) }
    }

    func suggestedEntities() async throws -> [MoodEntity] {
        MoodEntity.allMoods
    }

    func defaultResult() async -> MoodEntity? {
        MoodEntity.allMoods.first { $0.mood == .average }
    }
}

// MARK: - Log Mood Intent

struct LogMoodIntent: AppIntent {
    static var title: LocalizedStringResource = "Log Mood"
    static var description = IntentDescription("Record your mood for today in Reflect")
    static var openAppWhenRun: Bool = false

    @Parameter(title: "Mood")
    var moodEntity: MoodEntity

    static var parameterSummary: some ParameterSummary {
        Summary("Log mood as \(\.$moodEntity)")
    }

    @MainActor
    func perform() async throws -> some IntentResult & ProvidesDialog & ShowsSnippetView {
        let votingDate = ShowBasedOnVoteLogics.getCurrentVotingDate(onboardingData: UserDefaultsStore.getOnboarding())

        // Use centralized mood logger
        MoodLogger.shared.logMood(moodEntity.mood, for: votingDate, entryType: .siri)

        let moodTint = UserDefaultsStore.moodTintable()
        let color = moodTint.color(forMood: moodEntity.mood)

        return .result(
            dialog: "Got it! Logged \(moodEntity.name) for today.",
            view: MoodLoggedSnippetView(moodName: moodEntity.name, color: color)
        )
    }
}

// MARK: - Check Today's Mood Intent

struct CheckTodaysMoodIntent: AppIntent {
    static var title: LocalizedStringResource = "Check Today's Mood"
    static var description = IntentDescription("See what mood you logged today in Reflect")
    static var openAppWhenRun: Bool = false

    @MainActor
    func perform() async throws -> some IntentResult & ProvidesDialog {
        let votingDate = ShowBasedOnVoteLogics.getCurrentVotingDate(onboardingData: UserDefaultsStore.getOnboarding())
        let dayStart = Calendar.current.startOfDay(for: votingDate)
        let dayEnd = Calendar.current.date(bySettingHour: 23, minute: 59, second: 59, of: dayStart)!

        let todayEntry = DataController.shared.getData(startDate: dayStart, endDate: dayEnd, includedDays: []).first

        if let entry = todayEntry, entry.mood != .missing && entry.mood != .placeholder {
            return .result(dialog: "Today you logged feeling \(entry.mood.widgetDisplayName).")
        } else {
            return .result(dialog: "You haven't logged your mood today yet. Would you like to log it now?")
        }
    }
}

// MARK: - Get Mood Streak Intent

struct GetMoodStreakIntent: AppIntent {
    static var title: LocalizedStringResource = "Get Mood Streak"
    static var description = IntentDescription("Check your current mood logging streak")
    static var openAppWhenRun: Bool = false

    @MainActor
    func perform() async throws -> some IntentResult & ProvidesDialog {
        let streak = calculateStreak()

        if streak == 0 {
            return .result(dialog: "You don't have a streak yet. Log your mood today to start one!")
        } else if streak == 1 {
            return .result(dialog: "You have a 1 day streak. Keep it going!")
        } else {
            return .result(dialog: "Amazing! You have a \(streak) day streak. Keep it up!")
        }
    }

    @MainActor
    private func calculateStreak() -> Int {
        var streak = 0
        var checkDate = ShowBasedOnVoteLogics.getCurrentVotingDate(onboardingData: UserDefaultsStore.getOnboarding())

        while true {
            let dayStart = Calendar.current.startOfDay(for: checkDate)
            let dayEnd = Calendar.current.date(bySettingHour: 23, minute: 59, second: 59, of: dayStart)!

            let entry = DataController.shared.getData(startDate: dayStart, endDate: dayEnd, includedDays: []).first

            if let entry = entry, entry.mood != .missing && entry.mood != .placeholder {
                streak += 1
                checkDate = Calendar.current.date(byAdding: .day, value: -1, to: checkDate)!
            } else {
                break
            }
        }

        return streak
    }
}

// MARK: - Snippet View for Mood Logged

struct MoodLoggedSnippetView: View {
    let moodName: String
    let color: Color

    var body: some View {
        HStack(spacing: 12) {
            Circle()
                .fill(color)
                .frame(width: 44, height: 44)
                .overlay {
                    Image(systemName: "checkmark")
                        .font(.title2.bold())
                        .foregroundColor(.white)
                }

            VStack(alignment: .leading, spacing: 2) {
                Text("Mood Logged")
                    .font(.headline)
                Text(moodName)
                    .font(.subheadline)
                    .foregroundColor(color)
            }

            Spacer()
        }
        .padding()
    }
}

// MARK: - App Shortcuts Provider

struct ReflectShortcuts: AppShortcutsProvider {
    static var appShortcuts: [AppShortcut] {
        AppShortcut(
            intent: LogMoodIntent(),
            phrases: [
                "Log my mood in \(.applicationName)",
                "Log mood as \(\.$moodEntity) in \(.applicationName)",
                "Record my mood in \(.applicationName)",
                "I'm feeling \(\.$moodEntity) in \(.applicationName)",
                "Track my mood in \(.applicationName)"
            ],
            shortTitle: "Log Mood",
            systemImageName: "face.smiling"
        )

        AppShortcut(
            intent: CheckTodaysMoodIntent(),
            phrases: [
                "What's my mood today in \(.applicationName)",
                "Check today's mood in \(.applicationName)",
                "How am I feeling in \(.applicationName)"
            ],
            shortTitle: "Today's Mood",
            systemImageName: "calendar"
        )

        AppShortcut(
            intent: GetMoodStreakIntent(),
            phrases: [
                "What's my mood streak in \(.applicationName)",
                "Check my streak in \(.applicationName)",
                "How many days in a row in \(.applicationName)"
            ],
            shortTitle: "Mood Streak",
            systemImageName: "flame"
        )
    }
}

