//
//  ContentView.swift
//  SiiLibSample
//

import SwiftUI
import Foundation
import UniformTypeIdentifiers

struct ContentView: View {
    @ObservedObject var status: Status = Status()
    @ObservedObject var siiPrinterModel: SiiPrinterModel = SiiPrinterModel()

    @State var isShowPrinterModelSelectAlert: Bool = false
    @State var isStatusEnable: Bool = true
    @State var isShowSendDataFileDocumentPicker: Bool = false
    @State var isShowPrintPDFDocumentPicker: Bool = false
    @State var isShowSettingsSheet: Bool = false
    @State var isShowPrinterListSheet: Bool = false
    @State var viewDidLoad: Bool = false
    @State fileprivate var version: String = "SDK Version: "

    fileprivate static let printerManagerQueue = DispatchQueue(label: "com.sii-ps.printerManager")

    var body: some View {
        ZStack {
            VStack {
                NavigationStack {
                    VStack { // Printer informations stack
                        HStack {
                            Text("Address")
                            Spacer()
                        }
                        HStack {
                            TextField("", text: $siiPrinterModel.addressStr)
                                .frame(maxWidth: .infinity)
                                .disabled(true)
                                .textFieldStyle(.roundedBorder)
                            Spacer()
                            Button(action: {
                                isShowPrinterListSheet = true
                            },label: {
                                Text("Search")
                            })
                            .buttonStyle(.borderedProminent)
                            .sheet(isPresented: $isShowPrinterListSheet, content: {
                                // Turn to printerListView and start printer discovery
                                PrinterListView(siiPrinterModel: siiPrinterModel, isShowPrinterListSheet: $isShowPrinterListSheet)
                            })
                        }

                        HStack {
                            Text("Printer Model")
                            Spacer()
                        }
                        HStack {
                            // Button for select printer models
                            Button(action: {
                                isShowPrinterModelSelectAlert = true
                            }, label: {
                                HStack{
                                    Text(siiPrinterModel.modelName)
                                    Spacer()
                                }
                            })
                            .alert("", isPresented: $isShowPrinterModelSelectAlert, actions: {
                                let modelList: [String] = [
                                    PRINTER_MODEL_NAME_RPD10,
                                    PRINTER_MODEL_NAME_RPE10,
                                    PRINTER_MODEL_NAME_RPF10,
                                    PRINTER_MODEL_NAME_DPUS245,
                                    PRINTER_MODEL_NAME_DPUS445,
                                    PRINTER_MODEL_NAME_MPB20,
                                    PRINTER_MODEL_NAME_MPB21L,
                                    PRINTER_MODEL_NAME_MPB30,
                                    PRINTER_MODEL_NAME_MPB30L,
                                    PRINTER_MODEL_NAME_SLP720RT,
                                    PRINTER_MODEL_NAME_MPA40,]
                                ForEach(modelList, id:\.self){ model in
                                    Button(model){
                                        siiPrinterModel.modelName = model
                                        siiPrinterModel.printer.modelName = model
                                        siiPrinterModel.printer.model = siiPrinterModel.printer.getPrinterModel(modelName: model)
                                    }
                                }
                                Button("Cancel"){
                                    isShowPrinterModelSelectAlert = false
                                }
                            }, message: {
                                Text("Selet printer model")
                            })
                            .frame(maxWidth: .infinity)
                            .buttonStyle(.bordered)
                        }

                        // Toggle for control call back enable or disable
                        Toggle(isOn: $isStatusEnable, label: {
                            Text("Enable callback function when connecting")
                                .font(.footnote)
                                .lineLimit(2)
                        })
                        .padding(.horizontal)
                        .onChange(of: isStatusEnable, {
                            if isStatusEnable == true {
                                // When enable: set SIIPrinterManagerDelegate
                                SampleFunctions.setDelegate(delegate: status)
                            } else if isStatusEnable == false {
                                // When disable: set delegate to nil
                                SampleFunctions.disableDelegate()
                                status.resetStatus()
                            }
                        })
                    }

                    ScrollView { //Buttons stack
                        HStack {
                            Button(action: {
                                ContentView.printerManagerQueue.async {
                                    siiPrinterModel.showLoadingView(true)
                                    _ = SampleFunctions.connectSample(siiPrinterModel.printer.model, siiPrinterModel.printer.address, siiPrinterModel.printer.type)
                                    siiPrinterModel.setAlert(SampleFunctions.getResultMessage())
                                    siiPrinterModel.showLoadingView(false)
                                }
                            },label: {
                                Text("Connect")
                                    .frame(maxWidth: .infinity)
                            })
                            .buttonStyle(.borderedProminent)
                            Spacer()
                            Button(action: {
                                ContentView.printerManagerQueue.async {
                                    siiPrinterModel.showLoadingView(true)
                                    _ = SampleFunctions.disconnectSample()
                                    status.resetStatus()
                                    siiPrinterModel.setAlert(SampleFunctions.getResultMessage())
                                    siiPrinterModel.showLoadingView(false)
                                }
                            }, label: {
                                Text("Disconnect")
                                    .frame(maxWidth: .infinity)
                            })
                            .buttonStyle(.borderedProminent)
                        }

                        Button(action: {
                            ContentView.printerManagerQueue.async {
                                siiPrinterModel.showLoadingView(true)
                                _ = SampleFunctions.standardModeSample()
                                siiPrinterModel.setAlert(SampleFunctions.getResultMessage())
                                siiPrinterModel.showLoadingView(false)
                            }
                        },label: {
                            Text("Standard Mode Sample")
                                .frame(maxWidth: .infinity)
                        })
                        .buttonStyle(.borderedProminent)

                        Button(action: {
                            ContentView.printerManagerQueue.async {
                                siiPrinterModel.showLoadingView(true)
                                _ = SampleFunctions.printPageModeSample()
                                siiPrinterModel.setAlert(SampleFunctions.getResultMessage())
                                siiPrinterModel.showLoadingView(false)
                            }
                        }, label: {
                            Text("Page Mode Sample")
                                .frame(maxWidth: .infinity)
                        })
                        .buttonStyle(.borderedProminent)

                        Button(action: {
                            ContentView.printerManagerQueue.async {
                                siiPrinterModel.showLoadingView(true)
                                _ = SampleFunctions.smartLabelSample()
                                siiPrinterModel.setAlert(SampleFunctions.getResultMessage())
                                siiPrinterModel.showLoadingView(false)
                            }
                        }, label: {
                            Text("Smart Label Sample")
                                .frame(maxWidth: .infinity)
                        })
                        .buttonStyle(.borderedProminent)

                        Button(action: {
                            ContentView.printerManagerQueue.async {
                                siiPrinterModel.showLoadingView(true)
                                _ = SampleFunctions.displaySample()
                                siiPrinterModel.setAlert(SampleFunctions.getResultMessage())
                                siiPrinterModel.showLoadingView(false)
                            }
                        }, label: {Text("Display Sample")
                                .frame(maxWidth: .infinity)
                        })
                        .buttonStyle(.borderedProminent)

                        Button(action: {
                            // When button is touched, show a document picker
                            isShowSendDataFileDocumentPicker = true
                        }, label: {
                            Text("Send Data File")
                                .frame(maxWidth: .infinity)
                        })
                        .buttonStyle(.borderedProminent)
                        // The sendDataFile function allows following file extensions:
                        // .bmp, .jpg/.jpeg, .png, .txt, .bin, .dat, .htm/.html
                        .fileImporter(isPresented: $isShowSendDataFileDocumentPicker, allowedContentTypes: [
                            UTType(filenameExtension: "bmp")!,
                            UTType(filenameExtension: "jpg")!,
                            UTType(filenameExtension: "jpeg")!,
                            UTType(filenameExtension: "png")!,
                            UTType(filenameExtension: "txt")!,
                            UTType(filenameExtension: "bin")!,
                            UTType(filenameExtension: "dat")!,
                            UTType(filenameExtension: "htm")!,
                            UTType(filenameExtension: "html")!
                        ], allowsMultipleSelection: false, onCompletion: { result in
                            ContentView.printerManagerQueue.async {
                                var alertStr = ""
                                siiPrinterModel.showLoadingView(true)
                                if case .success = result {
                                    do {
                                        let file: URL = try result.get().first!
                                        if file.startAccessingSecurityScopedResource() == true {
                                            // Get selected file's path from url
                                            let filepath = file.path
                                            // Send file path to printer
                                            _ = SampleFunctions.sendDataFileSample(filepath)
                                            alertStr = SampleFunctions.getResultMessage()
                                        }
                                        file.stopAccessingSecurityScopedResource()
                                    } catch {
                                        alertStr = error.localizedDescription
                                    }
                                } else {
                                    alertStr = "File Import Failed"
                                }
                                siiPrinterModel.setAlert(alertStr)
                                siiPrinterModel.showLoadingView(false)
                            }
                        })

                        Button(action: {
                            // When button is touched, show a document picker
                            isShowPrintPDFDocumentPicker = true
                        }, label: {
                            Text("Print PDF")
                                .frame(maxWidth: .infinity)
                        })
                        .buttonStyle(.borderedProminent)
                        // The printPDF function allows following file extensions:
                        // .pdf
                        .fileImporter(isPresented: $isShowPrintPDFDocumentPicker, allowedContentTypes: [.pdf], allowsMultipleSelection: false, onCompletion: { result in
                            ContentView.printerManagerQueue.async {
                                var alertStr = ""
                                siiPrinterModel.showLoadingView(true)
                                if case .success = result {
                                    do {
                                        let file: URL = try result.get().first!
                                        if file.startAccessingSecurityScopedResource() == true {
                                            // Get selected file's path from url
                                            let filepath = file.path
                                            // Send file path to printer
                                            _ = SampleFunctions
                                                .printPDFSample(filepath)
                                            alertStr = SampleFunctions.getResultMessage()
                                        }
                                        file.stopAccessingSecurityScopedResource()
                                    } catch {
                                        alertStr = error.localizedDescription
                                    }
                                } else {
                                    alertStr = "File Import Failed"
                                }
                                siiPrinterModel.setAlert(alertStr)
                                siiPrinterModel.showLoadingView(false)
                            }
                        })

                        Button(action: {
                            ContentView.printerManagerQueue.async {
                                siiPrinterModel.showLoadingView(true)
                                _ = SampleFunctions.openDrawerSample()
                                siiPrinterModel.setAlert(SampleFunctions.getResultMessage())
                                siiPrinterModel.showLoadingView(false)
                            }
                        }, label: {
                            Text("Open Drawer")
                                .frame(maxWidth: .infinity)
                        })
                        .buttonStyle(.borderedProminent)
                    }

                    VStack { // Call back informations stack
                        // Call back properties are defined in Status class and changed by SIIPrinterManagerDelegate class
                        HStack {
                            VStack(alignment: .leading) {
                                Text("Printer Status")
                                    .font(.footnote)
                                TextField("", text: $status.printerStatusStr)
                                    .disabled(true)
                                    .textFieldStyle(.roundedBorder)
                            }
                            VStack(alignment: .leading) {
                                Text("Barcode Scanner Status")
                                    .font(.footnote)
                                TextField("", text: $status.barcodeStatus)
                                    .disabled(true)
                                    .textFieldStyle(.roundedBorder)
                            }
                        }
                        HStack {
                            VStack(alignment: .center) {
                                Text("String")
                                    .font(.footnote)
                                Toggle(isOn: $status.isBarcodeEncode, label: {
                                    Text("Enable barcode encode") .font(.footnote)
                                })
                                .labelsHidden()
                            }
                            VStack(alignment: .leading) {
                                Text("Scanned Data")
                                    .font(.footnote)
                                TextField("", text: $status.barcodeData)
                                    .disabled(true)
                                    .textFieldStyle(.roundedBorder)
                            }
                        }
                        HStack {
                            Spacer()
                            Text(version)
                                .font(.footnote)
                        }
                    }
                    .toolbar(content:{
                        ToolbarItem(placement: .automatic, content: {
                            Text("Sample")
                                .font(.title)
                        })
                        ToolbarItem(placement: .topBarTrailing, content: {
                            Button(action:{
                                isShowSettingsSheet = true
                            }, label: {
                                Image(systemName: "gear")
                            })
                            .sheet(
                                isPresented: $isShowSettingsSheet,
                                content: {
                                    SettingsView(isShowSettingsView: $isShowSettingsSheet)
                                })
                        })
                    })
                    .toolbarTitleDisplayMode(.inline)
                    .toolbarRole(.editor)
                }
                .padding()
            }
            .alert(siiPrinterModel.alertStr, isPresented: $siiPrinterModel.isShowAlert) {
                Button("OK") {
                    siiPrinterModel.setAlert("")
                }
            }
            if siiPrinterModel.isShowLoadingView == true {
                LoadingView()
            }
        }
        .onAppear() {
            if viewDidLoad == false {
                SampleFunctions.InitialSetting()
                SampleFunctions.setDelegate(delegate: status)
                version = version + SampleFunctions.getVersionSample()
                viewDidLoad = true
            }
        }
    }
}

#Preview {
    ContentView()
}
