//
//  LockScreenWidget.swift
//  AltWidget
//
//  Created by Riley Testut on 7/7/22.
//  Copyright © 2022 Riley Testut. All rights reserved.
//

import SwiftUI
import WidgetKit
import AltStoreCore

struct TextLockScreenWidget: Widget
{
    private let kind: String = "TextLockAppDetail"
    
    public var body: some WidgetConfiguration {
        if #available(iOSApplicationExtension 16, *)
        {
            return IntentConfiguration(kind: kind,
                                       intent: ViewAppIntent.self,
                                       provider: AppsTimelineProvider()) { (entry) in
                ComplicationView(entry: entry, style: .text)
            }
            .supportedFamilies([.accessoryCircular])
            .configurationDisplayName("AltWidget (Text)")
            .description("View remaining days until SideStore expires.")
        }
        else
        {
            return EmptyWidgetConfiguration()
        }
    }
}

struct IconLockScreenWidget: Widget
{
    private let kind: String = "IconLockAppDetail"
    
    public var body: some WidgetConfiguration {
        if #available(iOSApplicationExtension 16, *)
        {
            return IntentConfiguration(kind: kind,
                                       intent: ViewAppIntent.self,
                                       provider: AppsTimelineProvider()) { (entry) in
                ComplicationView(entry: entry, style: .icon)
            }
            .supportedFamilies([.accessoryCircular])
            .configurationDisplayName("AltWidget (Icon)")
            .description("View remaining days until SideStore expires.")
        }
        else
        {
            return EmptyWidgetConfiguration()
        }
    }
}

@available(iOS 16, *)
extension ComplicationView
{
    fileprivate enum Style
    {
        case text
        case icon
    }
}

@available(iOS 16, *)
private struct ComplicationView: View
{
    let entry: AppsEntry<Intent>
    let style: Style
    
    var body: some View {
        let refreshedDate = self.entry.apps.first?.refreshedDate ?? .now
        let expirationDate = self.entry.apps.first?.expirationDate ?? .now
        
        let totalDays = expirationDate.numberOfCalendarDays(since: refreshedDate)
        let daysRemaining = expirationDate.numberOfCalendarDays(since: self.entry.date)
        
        let progress = Double(daysRemaining) / Double(totalDays)
        
        // TODO: Gauge initialized with an out-of-bounds progress amount. The amount will be clamped to the nearest bound.
        Gauge(value: progress) {
            if daysRemaining < 0
            {
                Text("Expired")
                    .font(.system(size: 10, weight: .bold))
            }
            else
            {
                switch self.style
                {
                case .text:
                    VStack(spacing: -1) {
                        let fontSize = daysRemaining > 99 ? 18.0 : 20.0
                        Text("\(daysRemaining)")
                            .font(.system(size: fontSize, weight: .bold, design: .rounded))
                        
                        Text(daysRemaining == 1 ? "DAY" : "DAYS")
                            .font(.caption)
                    }
                    .fixedSize()
                    .offset(y: -1)
                    
                case .icon:
                    ZStack {
                        // Destination
                        Image("SmallIcon")
                            .resizable()
                            .aspectRatio(1.0, contentMode: .fill)
                            .scaleEffect(x: 0.8, y: 0.8)
                        
                        // Source
                        (
                            daysRemaining > 7 ?
                            Text("7+")
                                .font(.system(size: 18, weight: .bold, design: .rounded))
                                .kerning(-2) :
                                
                            Text("\(daysRemaining)")
                                .font(.system(size: 20, weight: .bold, design: .rounded))
                         )
                        .foregroundColor(Color.black)
                        .blendMode(.destinationOut) // Clip text out of image.
                    }
                }
            }
        }
        .gaugeStyle(.accessoryCircularCapacity)
        .unredacted()
        .widgetBackground(Color.clear)
    }
}

private let widgetFamily = if #available(iOS 16, *) { WidgetFamily.accessoryCircular } else { WidgetFamily.systemSmall }

@available(iOS 17, *)
#Preview("Text", as: widgetFamily) {
    TextLockScreenWidget()
} timeline: {
    let expiredDate = Date().addingTimeInterval(1 * 60 * 60 * 24 * 7)
    let (altstore, _, _, longAltStore, _, _) = AppSnapshot.makePreviewSnapshots()
    
    AppsEntry<Any>(date: Date(), apps: [altstore])
    AppsEntry<Any>(date: Date(), apps: [longAltStore])
    
    AppsEntry<Any>(date: expiredDate, apps: [altstore])
}

@available(iOS 17, *)
#Preview("Icon", as: widgetFamily) {
    IconLockScreenWidget()
} timeline: {
    let expiredDate = Date().addingTimeInterval(1 * 60 * 60 * 24 * 7)
    let (altstore, _, _, longAltStore, _, _) = AppSnapshot.makePreviewSnapshots()
    
    AppsEntry<Any>(date: Date(), apps: [altstore])
    AppsEntry<Any>(date: Date(), apps: [longAltStore])
    
    AppsEntry<Any>(date: expiredDate, apps: [altstore])
}
