//
//  honeyDue.swift
//  honeyDue
//
//  Created by Trey Tartt on 11/5/25.
//

import WidgetKit
import SwiftUI
import AppIntents

// MARK: - Date Formatting Helper

/// Cached formatters to avoid repeated allocation in widget rendering
private enum WidgetDateFormatters {
    static let dateOnly: DateFormatter = {
        let f = DateFormatter()
        f.dateFormat = "yyyy-MM-dd"
        return f
    }()

    static let iso8601WithFractional: ISO8601DateFormatter = {
        let f = ISO8601DateFormatter()
        f.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
        return f
    }()

    static let iso8601: ISO8601DateFormatter = {
        let f = ISO8601DateFormatter()
        f.formatOptions = [.withInternetDateTime]
        return f
    }()
}

/// Parses date strings in either yyyy-MM-dd or ISO8601 (RFC3339) format
/// and returns a user-friendly string like "Today" or "in X days"
private func formatWidgetDate(_ dateString: String) -> String {
    let calendar = Calendar.current
    var date: Date?

    // Try parsing as yyyy-MM-dd first
    date = WidgetDateFormatters.dateOnly.date(from: dateString)

    // Try parsing as ISO8601 (RFC3339) if that fails
    if date == nil {
        date = WidgetDateFormatters.iso8601WithFractional.date(from: dateString)

        // Try without fractional seconds
        if date == nil {
            date = WidgetDateFormatters.iso8601.date(from: dateString)
        }
    }

    guard let parsedDate = date else {
        return dateString
    }

    let today = calendar.startOfDay(for: Date())
    let dueDay = calendar.startOfDay(for: parsedDate)

    if calendar.isDateInToday(parsedDate) {
        return "Today"
    }

    let components = calendar.dateComponents([.day], from: today, to: dueDay)
    let days = components.day ?? 0

    if days > 0 {
        return days == 1 ? "in 1 day" : "in \(days) days"
    } else {
        let overdueDays = abs(days)
        return overdueDays == 1 ? "1 day ago" : "\(overdueDays) days ago"
    }
}

/// CacheManager reads tasks from the App Group shared container
/// Data is written by the main app via WidgetDataManager
class CacheManager {
    struct CustomTask: Codable, Identifiable {
        let id: Int
        let title: String
        let description: String?
        let priority: String?
        let inProgress: Bool
        let dueDate: String?
        let category: String?
        let residenceName: String?
        let isOverdue: Bool
        let isDueWithin7Days: Bool
        let isDue8To30Days: Bool

        enum CodingKeys: String, CodingKey {
            case id, title, description, priority, category
            case inProgress = "in_progress"
            case dueDate = "due_date"
            case residenceName = "residence_name"
            case isOverdue = "is_overdue"
            case isDueWithin7Days = "is_due_within_7_days"
            case isDue8To30Days = "is_due_8_to_30_days"
        }

        /// Whether this task is pending completion (tapped on widget, waiting for sync)
        var isPendingCompletion: Bool {
            WidgetActionManager.shared.isTaskPendingCompletion(taskId: id)
        }

        /// Whether this task should be shown (not pending completion)
        var shouldShow: Bool {
            !isPendingCompletion
        }
    }

    private static let appGroupIdentifier: String = {
        Bundle.main.infoDictionary?["AppGroupIdentifier"] as? String ?? "group.com.tt.honeyDue.dev"
    }()
    private static let tasksFileName = "widget_tasks.json"

    /// Get the shared App Group container URL
    private static var sharedContainerURL: URL? {
        FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupIdentifier)
    }

    /// Get the URL for the tasks file
    private static var tasksFileURL: URL? {
        sharedContainerURL?.appendingPathComponent(tasksFileName)
    }

    static func getData() -> [CustomTask] {
        guard let fileURL = tasksFileURL else {
            print("CacheManager: Unable to access shared container")
            return []
        }

        guard FileManager.default.fileExists(atPath: fileURL.path) else {
            print("CacheManager: No cached tasks file found")
            return []
        }

        do {
            let data = try Data(contentsOf: fileURL)
            let tasks = try JSONDecoder().decode([CustomTask].self, from: data)
            print("CacheManager: Loaded \(tasks.count) tasks from shared container")
            return tasks
        } catch {
            print("CacheManager: Error decoding tasks - \(error)")
            return []
        }
    }

    static func getUpcomingTasks() -> [CustomTask] {
        let allTasks = getData()

        // Filter for actionable tasks (not completed, including in-progress and overdue)
        // Also exclude tasks that are pending completion via widget
        let upcoming = allTasks.filter { task in
            // Include if: not pending completion
            return task.shouldShow
        }

        // Sort by due date (earliest first), with overdue at top
        return upcoming.sorted { task1, task2 in
            // Overdue tasks first
            if task1.isOverdue != task2.isOverdue {
                return task1.isOverdue
            }

            // Then by due date
            guard let date1 = task1.dueDate, let date2 = task2.dueDate else {
                return task1.dueDate != nil
            }
            return date1 < date2
        }
    }
}

struct Provider: AppIntentTimelineProvider {
    func placeholder(in context: Context) -> SimpleEntry {
        SimpleEntry(
            date: Date(),
            configuration: ConfigurationAppIntent(),
            upcomingTasks: [],
            isInteractive: true
        )
    }

    func snapshot(for configuration: ConfigurationAppIntent, in context: Context) async -> SimpleEntry {
        let tasks = CacheManager.getUpcomingTasks()
        let isInteractive = WidgetActionManager.shared.shouldShowInteractiveWidget()
        return SimpleEntry(
            date: Date(),
            configuration: configuration,
            upcomingTasks: tasks,
            isInteractive: isInteractive
        )
    }

    func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline<SimpleEntry> {
        let tasks = CacheManager.getUpcomingTasks()
        let isInteractive = WidgetActionManager.shared.shouldShowInteractiveWidget()

        // Use a longer refresh interval during overnight hours (11pm-6am)
        let currentDate = Date()
        let hour = Calendar.current.component(.hour, from: currentDate)
        let refreshMinutes = (hour >= 23 || hour < 6) ? 120 : 30
        let nextUpdate = Calendar.current.date(byAdding: .minute, value: refreshMinutes, to: currentDate)!
        let entry = SimpleEntry(
            date: currentDate,
            configuration: configuration,
            upcomingTasks: tasks,
            isInteractive: isInteractive
        )

        return Timeline(entries: [entry], policy: .after(nextUpdate))
    }
}

struct SimpleEntry: TimelineEntry {
    let date: Date
    let configuration: ConfigurationAppIntent
    let upcomingTasks: [CacheManager.CustomTask]
    let isInteractive: Bool

    var taskCount: Int {
        upcomingTasks.count
    }

    var nextTask: CacheManager.CustomTask? {
        upcomingTasks.first
    }

    /// Overdue tasks count - uses isOverdue flag from API column
    var overdueCount: Int {
        upcomingTasks.filter { $0.isOverdue }.count
    }

    /// Tasks due within the next 7 days
    var dueNext7DaysCount: Int {
        upcomingTasks.filter { $0.isDueWithin7Days }.count
    }

    /// Tasks due within 8-30 days
    var dueNext30DaysCount: Int {
        upcomingTasks.filter { $0.isDue8To30Days }.count
    }
}

struct HoneyDueEntryView : View {
    var entry: Provider.Entry
    @Environment(\.widgetFamily) var family

    var body: some View {
        if entry.isInteractive {
            // Premium/no-limitations: Show interactive widget with task completion
            switch family {
            case .systemSmall:
                SmallWidgetView(entry: entry)
            case .systemMedium:
                MediumWidgetView(entry: entry)
            case .systemLarge:
                LargeWidgetView(entry: entry)
            default:
                SmallWidgetView(entry: entry)
            }
        } else {
            // Free tier with limitations: Show simple task count view
            FreeWidgetView(entry: entry)
        }
    }
}

// MARK: - Free Tier Widget View (Non-Interactive)
struct FreeWidgetView: View {
    let entry: SimpleEntry
    @Environment(\.colorScheme) var colorScheme

    var body: some View {
        VStack(spacing: OrganicSpacing.cozy) {
            Spacer()

            // Organic task count with glow
            ZStack {
                // Soft glow behind number
                Circle()
                    .fill(
                        RadialGradient(
                            colors: [
                                Color.appPrimary.opacity(0.2),
                                Color.appPrimary.opacity(0.05),
                                Color.clear
                            ],
                            center: .center,
                            startRadius: 0,
                            endRadius: 50
                        )
                    )
                    .frame(width: 100, height: 100)

                Text("\(entry.taskCount)")
                    .font(.system(size: 52, weight: .bold, design: .rounded))
                    .foregroundStyle(
                        LinearGradient(
                            colors: [Color.appPrimary, Color.appPrimary.opacity(0.8)],
                            startPoint: .topLeading,
                            endPoint: .bottomTrailing
                        )
                    )
            }

            Text(entry.taskCount == 1 ? "task waiting" : "tasks waiting")
                .font(.system(size: 14, weight: .semibold, design: .rounded))
                .foregroundStyle(Color.appTextSecondary)
                .multilineTextAlignment(.center)

            Spacer()

            // Subtle upgrade hint with organic styling
            Text("Upgrade for interactive widgets")
                .font(.system(size: 10, weight: .medium, design: .rounded))
                .foregroundStyle(Color.appTextSecondary.opacity(0.6))
                .padding(.horizontal, 12)
                .padding(.vertical, 6)
                .background(
                    Capsule()
                        .fill(Color.appPrimary.opacity(colorScheme == .dark ? 0.15 : 0.08))
                )
        }
        .padding(OrganicSpacing.cozy)
    }
}

// MARK: - Small Widget View
struct SmallWidgetView: View {
    let entry: SimpleEntry
    @Environment(\.colorScheme) var colorScheme

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            // Task Count with organic glow
            HStack(alignment: .top) {
                VStack(alignment: .leading, spacing: 2) {
                    Text("\(entry.taskCount)")
                        .font(.system(size: 34, weight: .bold, design: .rounded))
                        .foregroundStyle(
                            LinearGradient(
                                colors: [Color.appPrimary, Color.appPrimary.opacity(0.8)],
                                startPoint: .topLeading,
                                endPoint: .bottomTrailing
                            )
                        )

                    if entry.taskCount > 0 {
                        Text(entry.taskCount == 1 ? "task" : "tasks")
                            .font(.system(size: 11, weight: .semibold, design: .rounded))
                            .foregroundStyle(Color.appTextSecondary)
                    }
                }

                Spacer()

                // Small decorative accent
                Circle()
                    .fill(
                        RadialGradient(
                            colors: [Color.appPrimary.opacity(0.15), Color.clear],
                            center: .center,
                            startRadius: 0,
                            endRadius: 20
                        )
                    )
                    .frame(width: 40, height: 40)
                    .offset(x: 10, y: -10)
            }

            Spacer(minLength: 8)

            // Next Task Card
            if let nextTask = entry.nextTask {
                VStack(alignment: .leading, spacing: 6) {
                    Text(nextTask.title)
                        .font(.system(size: 12, weight: .semibold, design: .rounded))
                        .lineLimit(1)
                        .foregroundStyle(Color.appTextPrimary)

                    HStack(spacing: 6) {
                        if let dueDate = nextTask.dueDate {
                            HStack(spacing: 3) {
                                Image(systemName: "calendar")
                                    .font(.system(size: 8, weight: .medium))
                                Text(formatWidgetDate(dueDate))
                                    .font(.system(size: 9, weight: .semibold, design: .rounded))
                            }
                            .foregroundStyle(nextTask.isOverdue ? Color.appError : Color.appAccent)
                            .padding(.horizontal, 6)
                            .padding(.vertical, 3)
                            .background(
                                Capsule()
                                    .fill((nextTask.isOverdue ? Color.appError : Color.appAccent).opacity(colorScheme == .dark ? 0.2 : 0.12))
                            )
                        }

                        Spacer()

                        // Organic complete button
                        Button(intent: CompleteTaskIntent(taskId: nextTask.id, taskTitle: nextTask.title)) {
                            ZStack {
                                Circle()
                                    .fill(Color.appPrimary.opacity(0.15))
                                    .frame(width: 28, height: 28)
                                Image(systemName: "checkmark")
                                    .font(.system(size: 12, weight: .bold))
                                    .foregroundStyle(Color.appPrimary)
                            }
                        }
                        .buttonStyle(.plain)
                    }
                }
                .padding(OrganicSpacing.compact)
                .frame(maxWidth: .infinity, alignment: .leading)
                .background(
                    RoundedRectangle(cornerRadius: 14, style: .continuous)
                        .fill(Color.appPrimary.opacity(colorScheme == .dark ? 0.12 : 0.08))
                )
            } else {
                // Empty state
                HStack(spacing: 8) {
                    ZStack {
                        Circle()
                            .fill(Color.appPrimary.opacity(0.15))
                            .frame(width: 24, height: 24)
                        Image(systemName: "checkmark")
                            .font(.system(size: 10, weight: .bold))
                            .foregroundStyle(Color.appPrimary)
                    }
                    Text("All caught up!")
                        .font(.system(size: 11, weight: .semibold, design: .rounded))
                        .foregroundStyle(Color.appTextSecondary)
                }
                .frame(maxWidth: .infinity)
                .padding(.vertical, 10)
                .background(
                    RoundedRectangle(cornerRadius: 14, style: .continuous)
                        .fill(Color.appPrimary.opacity(colorScheme == .dark ? 0.1 : 0.06))
                )
            }
        }
        .padding(14)
    }
}

// MARK: - Medium Widget View
struct MediumWidgetView: View {
    let entry: SimpleEntry
    @Environment(\.colorScheme) var colorScheme

    var body: some View {
        HStack(spacing: 0) {
            // Left side - Task count with organic styling
            VStack(alignment: .center, spacing: 4) {
                Spacer()

                ZStack {
                    // Soft glow
                    Circle()
                        .fill(
                            RadialGradient(
                                colors: [Color.appPrimary.opacity(0.15), Color.clear],
                                center: .center,
                                startRadius: 0,
                                endRadius: 35
                            )
                        )
                        .frame(width: 70, height: 70)

                    Text("\(entry.taskCount)")
                        .font(.system(size: 38, weight: .bold, design: .rounded))
                        .foregroundStyle(
                            LinearGradient(
                                colors: [Color.appPrimary, Color.appPrimary.opacity(0.8)],
                                startPoint: .topLeading,
                                endPoint: .bottomTrailing
                            )
                        )
                }

                Text(entry.taskCount == 1 ? "task" : "tasks")
                    .font(.system(size: 12, weight: .semibold, design: .rounded))
                    .foregroundStyle(Color.appTextSecondary)

                Spacer()
            }
            .frame(width: 85)

            // Organic divider
            Rectangle()
                .fill(
                    LinearGradient(
                        colors: [Color.appTextSecondary.opacity(0), Color.appTextSecondary.opacity(0.2), Color.appTextSecondary.opacity(0)],
                        startPoint: .top,
                        endPoint: .bottom
                    )
                )
                .frame(width: 1)
                .padding(.vertical, 12)

            // Right side - Task list
            VStack(alignment: .leading, spacing: 6) {
                if entry.nextTask != nil {
                    ForEach(Array(entry.upcomingTasks.prefix(3).enumerated()), id: \.element.id) { index, task in
                        OrganicTaskRowView(task: task, compact: true)
                    }
                    Spacer(minLength: 0)
                } else {
                    Spacer()
                    // Empty state
                    VStack(spacing: 8) {
                        ZStack {
                            Circle()
                                .fill(Color.appPrimary.opacity(0.15))
                                .frame(width: 36, height: 36)
                            Image(systemName: "checkmark")
                                .font(.system(size: 16, weight: .bold))
                                .foregroundStyle(Color.appPrimary)
                        }
                        Text("All caught up!")
                            .font(.system(size: 12, weight: .semibold, design: .rounded))
                            .foregroundStyle(Color.appTextSecondary)
                    }
                    .frame(maxWidth: .infinity)
                    Spacer()
                }
            }
            .frame(maxWidth: .infinity)
            .padding(.leading, 12)
        }
        .padding(14)
    }
}

// MARK: - Organic Task Row View
struct OrganicTaskRowView: View {
    let task: CacheManager.CustomTask
    var compact: Bool = false
    var showResidence: Bool = false
    @Environment(\.colorScheme) var colorScheme

    var body: some View {
        HStack(spacing: compact ? 8 : 10) {
            // Organic checkbox button
            Button(intent: CompleteTaskIntent(taskId: task.id, taskTitle: task.title)) {
                ZStack {
                    Circle()
                        .stroke(
                            LinearGradient(
                                colors: [priorityColor, priorityColor.opacity(0.7)],
                                startPoint: .topLeading,
                                endPoint: .bottomTrailing
                            ),
                            lineWidth: 2
                        )
                        .frame(width: compact ? 18 : 22, height: compact ? 18 : 22)

                    Circle()
                        .fill(priorityColor.opacity(colorScheme == .dark ? 0.15 : 0.1))
                        .frame(width: compact ? 14 : 18, height: compact ? 14 : 18)
                }
            }
            .buttonStyle(.plain)

            VStack(alignment: .leading, spacing: compact ? 2 : 3) {
                Text(task.title)
                    .font(.system(size: compact ? 11 : 12, weight: .semibold, design: .rounded))
                    .lineLimit(compact ? 1 : 2)
                    .foregroundStyle(Color.appTextPrimary)

                HStack(spacing: 8) {
                    if showResidence, let residenceName = task.residenceName, !residenceName.isEmpty {
                        HStack(spacing: 2) {
                            Image("icon")
                                .resizable()
                                .frame(width: 7, height: 7)
                            Text(residenceName)
                                .font(.system(size: 9, weight: .medium, design: .rounded))
                        }
                        .foregroundStyle(Color.appTextSecondary)
                    }

                    if let dueDate = task.dueDate {
                        HStack(spacing: 2) {
                            Image(systemName: "calendar")
                                .font(.system(size: 7, weight: .medium))
                            Text(formatWidgetDate(dueDate))
                                .font(.system(size: 9, weight: .semibold, design: .rounded))
                        }
                        .foregroundStyle(task.isOverdue ? Color.appError : Color.appAccent)
                    }
                }
            }

            Spacer(minLength: 0)
        }
        .padding(.vertical, compact ? 4 : 6)
        .padding(.horizontal, compact ? 6 : 8)
        .background(
            RoundedRectangle(cornerRadius: compact ? 10 : 12, style: .continuous)
                .fill(priorityColor.opacity(colorScheme == .dark ? 0.12 : 0.06))
        )
    }

    private var priorityColor: Color {
        if task.isOverdue {
            return Color.appError
        }
        switch task.priority?.lowercased() {
        case "urgent": return Color.appError
        case "high": return Color.appAccent
        case "medium": return Color(red: 0.92, green: 0.70, blue: 0.03) // Yellow
        default: return Color.appPrimary
        }
    }
}

// MARK: - Large Widget View
struct LargeWidgetView: View {
    let entry: SimpleEntry
    @Environment(\.colorScheme) var colorScheme

    private var maxTasksToShow: Int { 5 }

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            if entry.upcomingTasks.isEmpty {
                // Empty state - centered with organic styling
                Spacer()

                VStack(spacing: 14) {
                    ZStack {
                        Circle()
                            .fill(
                                RadialGradient(
                                    colors: [Color.appPrimary.opacity(0.2), Color.appPrimary.opacity(0.05), Color.clear],
                                    center: .center,
                                    startRadius: 0,
                                    endRadius: 40
                                )
                            )
                            .frame(width: 80, height: 80)

                        Image(systemName: "checkmark.circle.fill")
                            .font(.system(size: 44, weight: .medium))
                            .foregroundStyle(
                                LinearGradient(
                                    colors: [Color.appPrimary, Color.appPrimary.opacity(0.8)],
                                    startPoint: .topLeading,
                                    endPoint: .bottomTrailing
                                )
                            )
                    }

                    Text("All caught up!")
                        .font(.system(size: 16, weight: .semibold, design: .rounded))
                        .foregroundStyle(Color.appTextSecondary)
                }
                .frame(maxWidth: .infinity)

                Spacer()

                // Stats even when empty
                OrganicStatsView(entry: entry)
            } else {
                // Tasks section with organic rows
                VStack(alignment: .leading, spacing: 6) {
                    ForEach(Array(entry.upcomingTasks.prefix(maxTasksToShow).enumerated()), id: \.element.id) { index, task in
                        OrganicTaskRowView(task: task, showResidence: true)
                    }

                    if entry.upcomingTasks.count > maxTasksToShow {
                        Text("+ \(entry.upcomingTasks.count - maxTasksToShow) more")
                            .font(.system(size: 10, weight: .semibold, design: .rounded))
                            .foregroundStyle(Color.appTextSecondary)
                            .frame(maxWidth: .infinity, alignment: .center)
                            .padding(.top, 4)
                    }
                }

                Spacer(minLength: 10)

                // Stats section at bottom
                OrganicStatsView(entry: entry)
            }
        }
        .padding(14)
    }
}

// MARK: - Organic Stats View
struct OrganicStatsView: View {
    let entry: SimpleEntry
    @Environment(\.colorScheme) var colorScheme

    var body: some View {
        HStack(spacing: 8) {
            // Overdue
            OrganicStatPillWidget(
                value: entry.overdueCount,
                label: "Overdue",
                color: entry.overdueCount > 0 ? Color.appError : Color.appTextSecondary
            )

            // Next 7 Days
            OrganicStatPillWidget(
                value: entry.dueNext7DaysCount,
                label: "7 Days",
                color: Color.appAccent
            )

            // Next 30 Days
            OrganicStatPillWidget(
                value: entry.dueNext30DaysCount,
                label: "30 Days",
                color: Color.appPrimary
            )
        }
    }
}

// MARK: - Organic Stat Pill for Widget
struct OrganicStatPillWidget: View {
    let value: Int
    let label: String
    let color: Color
    @Environment(\.colorScheme) var colorScheme

    var body: some View {
        VStack(spacing: 3) {
            Text("\(value)")
                .font(.system(size: 18, weight: .bold, design: .rounded))
                .foregroundStyle(
                    LinearGradient(
                        colors: [color, color.opacity(0.8)],
                        startPoint: .topLeading,
                        endPoint: .bottomTrailing
                    )
                )

            Text(label)
                .font(.system(size: 9, weight: .semibold, design: .rounded))
                .foregroundStyle(Color.appTextSecondary)
                .lineLimit(1)
        }
        .frame(maxWidth: .infinity)
        .padding(.vertical, 10)
        .background(
            RoundedRectangle(cornerRadius: 12, style: .continuous)
                .fill(color.opacity(colorScheme == .dark ? 0.15 : 0.08))
        )
    }
}

struct honeyDue: Widget {
    let kind: String = "honeyDue"

    var body: some WidgetConfiguration {
        AppIntentConfiguration(kind: kind, intent: ConfigurationAppIntent.self, provider: Provider()) { entry in
            HoneyDueEntryView(entry: entry)
                .containerBackground(for: .widget) {
                    // Organic warm gradient background
                    ZStack {
                        Color.appBackgroundPrimary

                        // Subtle accent gradient
                        LinearGradient(
                            colors: [
                                Color.appPrimary.opacity(0.06),
                                Color.clear
                            ],
                            startPoint: .topLeading,
                            endPoint: .bottomTrailing
                        )

                        // Honeycomb pattern overlay (if enabled)
                        if HoneycombSetting.isEnabled {
                            HoneycombTexture(opacity: 0.10)
                        }
                    }
                }
        }
        .configurationDisplayName("honeyDue Tasks")
        .description("View and complete your upcoming tasks.")
        .supportedFamilies([.systemSmall, .systemMedium, .systemLarge])
    }
}

// MARK: - Previews
#Preview(as: .systemSmall) {
    honeyDue()
} timeline: {
    SimpleEntry(
        date: .now,
        configuration: ConfigurationAppIntent(),
        upcomingTasks: [
            CacheManager.CustomTask(
                id: 1,
                title: "Fix leaky faucet",
                description: "Kitchen sink needs repair",
                priority: "high",
                inProgress: false,
                dueDate: "2024-12-15",
                category: "plumbing",
                residenceName: "Home",
                isOverdue: false,
                isDueWithin7Days: true,
                isDue8To30Days: false
            ),
            CacheManager.CustomTask(
                id: 2,
                title: "Paint living room",
                description: nil,
                priority: "medium",
                inProgress: false,
                dueDate: "2024-12-20",
                category: "painting",
                residenceName: "Home",
                isOverdue: false,
                isDueWithin7Days: true,
                isDue8To30Days: false
            )
        ],
        isInteractive: true
    )

    // Free tier preview
    SimpleEntry(
        date: .now,
        configuration: ConfigurationAppIntent(),
        upcomingTasks: [
            CacheManager.CustomTask(
                id: 1,
                title: "Fix leaky faucet",
                description: nil,
                priority: "high",
                inProgress: false,
                dueDate: "2024-12-15",
                category: "plumbing",
                residenceName: "Home",
                isOverdue: false,
                isDueWithin7Days: true,
                isDue8To30Days: false
            ),
            CacheManager.CustomTask(
                id: 2,
                title: "Paint living room",
                description: nil,
                priority: "medium",
                inProgress: false,
                dueDate: "2024-12-20",
                category: "painting",
                residenceName: "Home",
                isOverdue: false,
                isDueWithin7Days: true,
                isDue8To30Days: false
            ),
            CacheManager.CustomTask(
                id: 3,
                title: "Clean gutters",
                description: nil,
                priority: "low",
                inProgress: false,
                dueDate: "2024-12-25",
                category: "maintenance",
                residenceName: "Home",
                isOverdue: false,
                isDueWithin7Days: false,
                isDue8To30Days: true
            )
        ],
        isInteractive: false
    )

    SimpleEntry(
        date: .now,
        configuration: ConfigurationAppIntent(),
        upcomingTasks: [],
        isInteractive: true
    )
}

#Preview(as: .systemMedium) {
    honeyDue()
} timeline: {
    SimpleEntry(
        date: .now,
        configuration: ConfigurationAppIntent(),
        upcomingTasks: [
            CacheManager.CustomTask(
                id: 1,
                title: "Fix leaky faucet",
                description: "Kitchen sink needs repair",
                priority: "high",
                inProgress: false,
                dueDate: "2024-12-15",
                category: "plumbing",
                residenceName: "Home",
                isOverdue: true,
                isDueWithin7Days: false,
                isDue8To30Days: false
            ),
            CacheManager.CustomTask(
                id: 2,
                title: "Paint living room",
                description: nil,
                priority: "medium",
                inProgress: true,
                dueDate: "2024-12-20",
                category: "painting",
                residenceName: "Cabin",
                isOverdue: false,
                isDueWithin7Days: true,
                isDue8To30Days: false
            ),
            CacheManager.CustomTask(
                id: 3,
                title: "Clean gutters",
                description: "Remove debris",
                priority: "low",
                inProgress: false,
                dueDate: "2024-12-25",
                category: "maintenance",
                residenceName: "Home",
                isOverdue: false,
                isDueWithin7Days: false,
                isDue8To30Days: true
            )
        ],
        isInteractive: true
    )

    // Free tier preview
    SimpleEntry(
        date: .now,
        configuration: ConfigurationAppIntent(),
        upcomingTasks: [
            CacheManager.CustomTask(
                id: 1,
                title: "Fix leaky faucet",
                description: nil,
                priority: "high",
                inProgress: false,
                dueDate: nil,
                category: nil,
                residenceName: nil,
                isOverdue: false,
                isDueWithin7Days: true,
                isDue8To30Days: false
            ),
            CacheManager.CustomTask(
                id: 2,
                title: "Paint living room",
                description: nil,
                priority: "medium",
                inProgress: false,
                dueDate: nil,
                category: nil,
                residenceName: nil,
                isOverdue: false,
                isDueWithin7Days: true,
                isDue8To30Days: false
            ),
            CacheManager.CustomTask(
                id: 3,
                title: "Clean gutters",
                description: nil,
                priority: "low",
                inProgress: false,
                dueDate: nil,
                category: nil,
                residenceName: nil,
                isOverdue: false,
                isDueWithin7Days: false,
                isDue8To30Days: true
            ),
            CacheManager.CustomTask(
                id: 4,
                title: "Replace HVAC filter",
                description: nil,
                priority: "medium",
                inProgress: false,
                dueDate: nil,
                category: nil,
                residenceName: nil,
                isOverdue: false,
                isDueWithin7Days: false,
                isDue8To30Days: true
            ),
            CacheManager.CustomTask(
                id: 5,
                title: "Check smoke detectors",
                description: nil,
                priority: "high",
                inProgress: false,
                dueDate: nil,
                category: nil,
                residenceName: nil,
                isOverdue: false,
                isDueWithin7Days: true,
                isDue8To30Days: false
            )
        ],
        isInteractive: false
    )

    SimpleEntry(
        date: .now,
        configuration: ConfigurationAppIntent(),
        upcomingTasks: [],
        isInteractive: true
    )
}

#Preview(as: .systemLarge) {
    honeyDue()
} timeline: {
    SimpleEntry(
        date: .now,
        configuration: ConfigurationAppIntent(),
        upcomingTasks: [
            CacheManager.CustomTask(
                id: 1,
                title: "Fix leaky faucet in kitchen",
                description: "Kitchen sink needs repair",
                priority: "high",
                inProgress: false,
                dueDate: "2024-12-15",
                category: "plumbing",
                residenceName: "Home",
                isOverdue: true,
                isDueWithin7Days: false,
                isDue8To30Days: false
            ),
            CacheManager.CustomTask(
                id: 2,
                title: "Paint living room walls",
                description: nil,
                priority: "medium",
                inProgress: true,
                dueDate: "2024-12-20",
                category: "painting",
                residenceName: "Cabin",
                isOverdue: false,
                isDueWithin7Days: true,
                isDue8To30Days: false
            ),
            CacheManager.CustomTask(
                id: 3,
                title: "Clean gutters",
                description: "Remove debris",
                priority: "low",
                inProgress: false,
                dueDate: "2024-12-25",
                category: "maintenance",
                residenceName: "Home",
                isOverdue: false,
                isDueWithin7Days: true,
                isDue8To30Days: false
            ),
            CacheManager.CustomTask(
                id: 4,
                title: "Replace HVAC filter",
                description: nil,
                priority: "medium",
                inProgress: false,
                dueDate: "2024-12-28",
                category: "hvac",
                residenceName: "Beach House",
                isOverdue: false,
                isDueWithin7Days: true,
                isDue8To30Days: false
            ),
            CacheManager.CustomTask(
                id: 5,
                title: "Check smoke detectors",
                description: "Replace batteries if needed",
                priority: "high",
                inProgress: false,
                dueDate: "2024-12-30",
                category: "safety",
                residenceName: "Home",
                isOverdue: false,
                isDueWithin7Days: false,
                isDue8To30Days: true
            ),
            CacheManager.CustomTask(
                id: 6,
                title: "Service water heater",
                description: nil,
                priority: "medium",
                inProgress: false,
                dueDate: "2025-01-05",
                category: "plumbing",
                residenceName: "Cabin",
                isOverdue: false,
                isDueWithin7Days: false,
                isDue8To30Days: true
            ),
            CacheManager.CustomTask(
                id: 7,
                title: "Inspect roof shingles",
                description: nil,
                priority: "low",
                inProgress: false,
                dueDate: "2025-01-10",
                category: "exterior",
                residenceName: "Home",
                isOverdue: false,
                isDueWithin7Days: false,
                isDue8To30Days: true
            ),
            CacheManager.CustomTask(
                id: 8,
                title: "Clean dryer vent",
                description: "Fire hazard prevention",
                priority: "urgent",
                inProgress: false,
                dueDate: "2025-01-12",
                category: "appliances",
                residenceName: "Beach House",
                isOverdue: false,
                isDueWithin7Days: false,
                isDue8To30Days: true
            )
        ],
        isInteractive: true
    )

    // Free tier preview
    SimpleEntry(
        date: .now,
        configuration: ConfigurationAppIntent(),
        upcomingTasks: [
            CacheManager.CustomTask(
                id: 1,
                title: "Task 1",
                description: nil,
                priority: "high",
                inProgress: false,
                dueDate: nil,
                category: nil,
                residenceName: nil,
                isOverdue: false,
                isDueWithin7Days: false,
                isDue8To30Days: false
            ),
            CacheManager.CustomTask(
                id: 2,
                title: "Task 2",
                description: nil,
                priority: "medium",
                inProgress: false,
                dueDate: nil,
                category: nil,
                residenceName: nil,
                isOverdue: false,
                isDueWithin7Days: false,
                isDue8To30Days: false
            ),
            CacheManager.CustomTask(
                id: 3,
                title: "Task 3",
                description: nil,
                priority: "low",
                inProgress: false,
                dueDate: nil,
                category: nil,
                residenceName: nil,
                isOverdue: false,
                isDueWithin7Days: false,
                isDue8To30Days: false
            ),
            CacheManager.CustomTask(
                id: 4,
                title: "Task 4",
                description: nil,
                priority: "medium",
                inProgress: false,
                dueDate: nil,
                category: nil,
                residenceName: nil,
                isOverdue: false,
                isDueWithin7Days: false,
                isDue8To30Days: false
            ),
            CacheManager.CustomTask(
                id: 5,
                title: "Task 5",
                description: nil,
                priority: "high",
                inProgress: false,
                dueDate: nil,
                category: nil,
                residenceName: nil,
                isOverdue: false,
                isDueWithin7Days: false,
                isDue8To30Days: false
            ),
            CacheManager.CustomTask(
                id: 6,
                title: "Task 6",
                description: nil,
                priority: "low",
                inProgress: false,
                dueDate: nil,
                category: nil,
                residenceName: nil,
                isOverdue: false,
                isDueWithin7Days: false,
                isDue8To30Days: false
            ),
            CacheManager.CustomTask(
                id: 7,
                title: "Task 7",
                description: nil,
                priority: "medium",
                inProgress: false,
                dueDate: nil,
                category: nil,
                residenceName: nil,
                isOverdue: false,
                isDueWithin7Days: false,
                isDue8To30Days: false
            )
        ],
        isInteractive: false
    )

    SimpleEntry(
        date: .now,
        configuration: ConfigurationAppIntent(),
        upcomingTasks: [],
        isInteractive: true
    )
}
