//
//  AboutView.swift
//  Tusker
//
//  Created by Shadowfacts on 12/21/22.
//  Copyright © 2022 Shadowfacts. All rights reserved.
//

import SwiftUI
import MessageUI

struct AboutView: View {
    @State private var logData: Data?
    @State private var isGettingLogData = false
    @State private var isShowingMailSheet = false
    
    private var version: String {
        let marketing = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
        let build = Bundle.main.infoDictionary?["CFBundleVersion"] as? String
        return "\(marketing ?? "<unknown>") (\(build ?? "<unknown>"))"
    }
    
    var body: some View {
        List {
            iconOrGame
                .frame(maxWidth: .infinity, alignment: .center)
                .listRowInsets(EdgeInsets(top: 9, leading: 0, bottom: 0, trailing: 0))
                .listRowBackground(EmptyView())
            
            Section {
                HStack {
                    Text("Version")
                    Spacer()
                    Text(version)
                        .foregroundColor(.secondary)
                }
                .contextMenu {
                    Button {
                        UIPasteboard.general.string = version
                    } label: {
                        Label("Copy", systemImage: "doc.on.doc")
                    }
                }
            }
            .appGroupedListRowBackground()
            
            Section {
                Link(destination: URL(string: "https://vaccor.space/tusker")!) {
                    Label("Website", systemImage: "safari")
                }
                Button {
                    if MFMailComposeViewController.canSendMail() {
                        Task {
                            await showMailSheet()
                        }
                    } else {
                        UIApplication.shared.open(URL(string: "mailto:hello@vaccor.space?subject=Tusker%20Support")!)
                    }
                } label: {
                    HStack {
                        Label("Get Support", systemImage: "envelope")
                        Spacer()
                        if isGettingLogData {
                            ProgressView()
                                .progressViewStyle(.circular)
                        }
                    }
                }
                .disabled(isGettingLogData)
                Link(destination: URL(string: "https://git.shadowfacts.net/shadowfacts/Tusker")!) {
                    Label("Source Code", systemImage: "curlybraces")
                }
                Link(destination: URL(string: "https://git.shadowfacts.net/shadowfacts/Tusker/issues")!) {
                    Label("Issue Tracker", systemImage: "checklist")
                }
            }
            .labelStyle(AboutLinksLabelStyle())
            .appGroupedListRowBackground()
        }
        .listStyle(.insetGrouped)
        .appGroupedListBackground(container: PreferencesNavigationController.self)
        .sheet(isPresented: $isShowingMailSheet) {
            MailSheet(logData: logData)
        }
    }
    
    @ViewBuilder
    private var iconOrGame: some View {
        if #available(iOS 16.0, *) {
            FlipView {
                appIcon
            } back: {
                TTTView()
            }
        } else {
            appIcon
        }
    }
    
    private var appIcon: some View {
        VStack {
            AppIconView()
                .shadow(radius: 6, y: 3)
                .frame(width: 256, height: 256)
            
            Text("Tusker")
                .font(.title2.bold())
        }
    }
    
    private func showMailSheet() async {
        isGettingLogData = true
        logData = await withCheckedContinuation({ continuation in
            DispatchQueue.global().async {
                continuation.resume(returning: Logging.getLogData())
            }
        })
        isGettingLogData = false
        isShowingMailSheet = true
    }
}

private struct AppIconView: UIViewRepresentable {
    func makeUIView(context: Context) -> UIImageView {
        let view = UIImageView(image: UIImage(named: "AboutIcon"))
        view.contentMode = .scaleAspectFit
        view.layer.cornerRadius = 256 / 6.4
        view.layer.cornerCurve = .continuous
        view.layer.masksToBounds = true
        return view
    }
    
    func updateUIView(_ uiView: UIImageView, context: Context) {
    }
}

private struct MailSheet: UIViewControllerRepresentable {
    typealias UIViewControllerType = MFMailComposeViewController
    
    let logData: Data?
    
    @Environment(\.dismiss) private var dismiss
    
    func makeUIViewController(context: Context) -> MFMailComposeViewController {
        let vc = MFMailComposeViewController()
        vc.mailComposeDelegate = context.coordinator
        vc.setToRecipients(["hello@vaccor.space"])
        vc.setSubject("Tusker Support")
        if let logData {
            let timestamp = ISO8601DateFormatter().string(from: Date())
            vc.addAttachmentData(logData, mimeType: "text/plain", fileName: "Tusker-\(timestamp).log")
        }
        return vc
    }
    
    func updateUIViewController(_ uiViewController: MFMailComposeViewController, context: Context) {
    }
    
    func makeCoordinator() -> Coordinator {
        return Coordinator(dismiss: dismiss)
    }
    
    class Coordinator: NSObject, MFMailComposeViewControllerDelegate {
        let dismiss: DismissAction
        
        init(dismiss: DismissAction) {
            self.dismiss = dismiss
        }
        
        func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
            dismiss()
        }
    }
}

private struct AboutLinksLabelStyle: LabelStyle {
    func makeBody(configuration: Configuration) -> some View {
        HStack(alignment: .lastTextBaseline, spacing: 8) {
            configuration.icon
            configuration.title
        }
    }
}

struct AboutView_Previews: PreviewProvider {
    static var previews: some View {
        AboutView()
    }
}
