//
//  HomeScreenWidget.swift
//  AltWidgetExtension
//
//  Created by Riley Testut on 8/16/23.
//  Copyright © 2023 Riley Testut. All rights reserved.
//

import SwiftUI
import WidgetKit
import CoreData

import AltStoreCore
import AltSign

private extension Color
{
    static let altGradientLight = Color.init(.displayP3, red: 123.0/255.0, green: 200.0/255.0, blue: 176.0/255.0)
    static let altGradientDark = Color.init(.displayP3, red: 0.0/255.0, green: 128.0/255.0, blue: 132.0/255.0)
    
    static let altGradientExtraDark = Color.init(.displayP3, red: 2.0/255.0, green: 82.0/255.0, blue: 103.0/255.0)
}

//@available(iOS 17, *)
struct ActiveAppsWidget: Widget
{
    private let kind: String = "ActiveApps"
    
    public var body: some WidgetConfiguration {
        if #available(iOS 17, *)
        {
            return StaticConfiguration(kind: kind, provider: AppsTimelineProvider()) { entry in
                ActiveAppsWidgetView(entry: entry)
            }
            .supportedFamilies([.systemMedium])
            .configurationDisplayName("Active Apps")
            .description("View remaining days until your active apps expire. Tap the countdown timers to refresh them in the background.")
        }
        else
        {
            // Can't mark ActiveAppsWidget as requiring iOS 17 directly without causing crash on older versions.
            // So instead we just return EmptyWidgetConfiguration pre-iOS 17.
            return EmptyWidgetConfiguration()
        }
    }
}

@available(iOS 17, *)
private struct ActiveAppsWidgetView: View
{
    var entry: AppsEntry
    
    @Environment(\.colorScheme)
    private var colorScheme
    
    var body: some View {
        Group {
            if entry.apps.isEmpty
            {
                placeholder
            }
            else
            {
                content
            }
        }
        .foregroundStyle(.white)
        .containerBackground(for: .widget) {
            if colorScheme == .dark
            {
                LinearGradient(colors: [.altGradientDark, .altGradientExtraDark], startPoint: .top, endPoint: .bottom)
            }
            else
            {
                LinearGradient(colors: [.altGradientLight, .altGradientDark], startPoint: .top, endPoint: .bottom)
            }
        }
    }
    
    private var content: some View {
        GeometryReader { (geometry) in
            
            let numberOfApps = max(entry.apps.count, 1) // Ensure we don't divide by 0
            let preferredRowHeight = (geometry.size.height / Double(numberOfApps)) - 8
            let rowHeight = min(preferredRowHeight, geometry.size.height / 2)
            
            ZStack(alignment: .center) {
                VStack(spacing: 12) {
                    ForEach(entry.apps, id: \.bundleIdentifier) { app in
                        
                        let daysRemaining = app.expirationDate.numberOfCalendarDays(since: entry.date)
                        let cornerRadius = rowHeight / 5.0
                        
                        HStack(spacing: 10) {
                            Image(uiImage: app.icon ?? UIImage(named: "AltStore")!)
                                .resizable()
                                .aspectRatio(contentMode: .fit)
                                .cornerRadius(cornerRadius)
                            
                            VStack(alignment: .leading, spacing: 1) {
                                Text(app.name)
                                    .font(.system(size: 15, weight: .semibold, design: .rounded))
                                
                                let text = if entry.date > app.expirationDate
                                {
                                    Text("Expired")
                                }
                                else
                                {
                                    Text("Expires in \(daysRemaining) ") + (daysRemaining == 1 ? Text("day") : Text("days"))
                                }
                                
                                text
                                    .font(.system(size: 13, weight: .semibold, design: .rounded))
                                    .foregroundStyle(.secondary)
                            }
                            
                            Spacer()
                            
                            Countdown(startDate: app.refreshedDate,
                                      endDate: app.expirationDate,
                                      currentDate: entry.date,
                                      strokeWidth: 3.0) // Slightly thinner circle stroke width
                            .background {
                                Color.black.opacity(0.1)
                                    .mask(Capsule())
                                    .padding(.all, -5)
                            }
                            .font(.system(size: 16, weight: .semibold, design: .rounded))
                            .invalidatableContent()
                            .padding(.horizontal, 8)
                            .activatesRefreshAllAppsIntent()
                        }
                        .frame(height: rowHeight)
                    }
                }
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
        }
    }
    
    private var placeholder: some View {
        Text("App Not Found")
            .font(.system(.body, design: .rounded))
            .fontWeight(.semibold)
            .foregroundColor(Color.white.opacity(0.4))
    }
}

@available(iOS 17, *)
#Preview(as: .systemMedium) {
    return ActiveAppsWidget()
} timeline: {
    let expiredDate = Date().addingTimeInterval(1 * 60 * 60 * 24 * 7)
    let (altstore, delta, clip, longAltStore, longDelta, longClip) = AppSnapshot.makePreviewSnapshots()
    
    AppsEntry(date: Date(), apps: [altstore, delta, clip])
    AppsEntry(date: Date(), apps: [longAltStore, longDelta, longClip])
    
    AppsEntry(date: expiredDate, apps: [altstore, delta, clip])
    
    AppsEntry(date: Date(), apps: [altstore, delta])
    AppsEntry(date: Date(), apps: [altstore])
    
    AppsEntry(date: Date(), apps: [])
    AppsEntry(date: Date(), apps: [], isPlaceholder: true)
}
