//
//  FirstView.swift
//  SIIMpaPrinterSample
//

import SwiftUI
import SIIMpaPrinterManager
import UniformTypeIdentifiers

struct FirstView: View {
    @ObservedObject var printerViewModel: PrinterViewModel
    @State var isShowPrinterListView: Bool = false
    @State var isShowSendDataFileView: Bool = false
    @State var isShowSendDataFileAlert: Bool = false
    @State var sendDataFileURL: URL = URL(fileURLWithPath: "")
    @State var isSendDataFileImageFile: Bool = false
    @State var sendDataFileAlertMessage: String = ""
    @State var isShowPDFFilePicker: Bool = false
    @State var isShowPrintPDFView: Bool = false
    @State var printPDFFileURL: URL = URL(fileURLWithPath: "")
    var body: some View {
        ZStack {
            NavigationStack {
                VStack {
                    VStack { // Printer informations stack
                        HStack {
                            Text("Address")
                            Spacer()
                        }
                        HStack {
                            TextField("", text:$printerViewModel.printer.address)
                                .frame(maxWidth: .infinity)
                                .disabled(true)
                                .textFieldStyle(.roundedBorder)
                            Spacer()
                            Button(action: {
                                isShowPrinterListView = true
                            },label: {
                                Text("Search")
                            })
                            .buttonStyle(.borderedProminent)
                            .sheet(isPresented: $isShowPrinterListView, content: {
                                // Turn to printerListView and start printer discovery
                                PrinterListView(printerViewModel: printerViewModel, isShowPrinterListView: $isShowPrinterListView)
                            })
                        }
                        
                        HStack {
                            Text("Connection type")
                            Spacer()
                        }
                        TextField("", text:$printerViewModel.printer.portType)
                            .frame(maxWidth: .infinity)
                            .disabled(true)
                            .textFieldStyle(.roundedBorder)
                    }
                    .padding()
                    
                    ScrollView {
                        NavigationLink(destination: CallBackFunctionView(printerViewModel: printerViewModel), label: {
                            Text("CallBackFunction")
                                .frame(maxWidth: .infinity)
                        })
                        .buttonStyle(.borderedProminent)
                        
                        NavigationLink(destination: PrinterInformationView(printerViewModel: printerViewModel), label: {
                            Text("PrinterInformation")
                                .frame(maxWidth: .infinity)
                        })
                        .buttonStyle(.borderedProminent)
                        
                        Button(action: {
                            PrinterManager.getDispatchQueue().async {
                                printerViewModel.showIndicator(true)
                                _ = PrinterManager.printStandardModeReceipt()
                                printerViewModel.setAlert(PrinterManager.getResultString())
                                printerViewModel.showIndicator(false)
                            }
                        }, label: {
                            Text("StandardModeSample")
                                .frame(maxWidth: .infinity)
                        })
                        .buttonStyle(.borderedProminent)
                        
                        Button(action: {
                            PrinterManager.getDispatchQueue().async {
                                printerViewModel.showIndicator(true)
                                _ = PrinterManager.printPageModeReceipt()
                                printerViewModel.setAlert(PrinterManager.getResultString())
                                printerViewModel.showIndicator(false)
                            }
                            
                        }, label: {
                            Text("PageModeSample")
                                .frame(maxWidth: .infinity)
                        })
                        .buttonStyle(.borderedProminent)
                        
                        NavigationLink(destination: TextFormattingView(printerViewModel: printerViewModel), label: {
                            Text("TextFormatting")
                                .frame(maxWidth: .infinity)
                        })
                        .buttonStyle(.borderedProminent)
                        
                        Button(action: {
                            // When button is touched, show a document picker
                            isShowSendDataFileView = true
                        }, label: {
                            Text("SendDataFile")
                                .frame(maxWidth: .infinity)
                        })
                        .buttonStyle(.borderedProminent)
                        // The sendDataFile function allows following file extensions:
                        // .bmp, .jpg/.jpeg, .png, .txt, .bin, .dat, .html
                        .fileImporter(isPresented: $isShowSendDataFileView, 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
                            if case .success = result {
                                do {
                                    let file: URL = try result.get().first!
                                    // Get selected file's path from url
                                    sendDataFileURL = file
                                    let ext = file.pathExtension.lowercased()
                                    if ext == "bmp" || ext == "jpg" || ext == "jpeg" || ext == "png" {
                                        isSendDataFileImageFile = true
                                        sendDataFileAlertMessage = "Send file: " +  sendDataFileURL.lastPathComponent + "\nSpecify dithering for printing."
                                        isShowSendDataFileAlert = true
                                    } else if ext == "txt" || ext == "bin" || ext == "dat" || ext == "html" || ext == "htm" {
                                        isSendDataFileImageFile = false
                                        sendDataFileAlertMessage = "Send file: " +  sendDataFileURL.lastPathComponent
                                        isShowSendDataFileAlert = true
                                    } else {
                                        //Unsupport file extension
                                        printerViewModel.setAlert("Unsupport file extension!")
                                    }
                                } catch {
                                    printerViewModel.setAlert(error.localizedDescription)
                                }
                            } else {
                                printerViewModel.setAlert("File Import Failed")
                            }
                        })
                        .alert("SendDataFile", isPresented: $isShowSendDataFileAlert, actions: {
                            if isSendDataFileImageFile == true {
                                Button("Dithering Enable") {
                                    sendDataFile(file: sendDataFileURL, dithering: true)
                                }
                                Button("Dithering Disable") {
                                    sendDataFile(file: sendDataFileURL, dithering: false)
                                }
                                Button("Cancel") {
                                    sendDataFileURL = URL(fileURLWithPath: "")
                                    isSendDataFileImageFile = false
                                }
                            } else {
                                Button("Cancel") {
                                    sendDataFileURL = URL(fileURLWithPath: "")
                                    isSendDataFileImageFile = false
                                }
                                Button("Send") {
                                    sendDataFile(file: sendDataFileURL, dithering: false)
                                }
                            }
                        }, message: {
                            Text(sendDataFileAlertMessage)
                        })

                        Button(action: {
                            // When button is touched, show a document picker
                                isShowPDFFilePicker = true
                        }, label: {
                            Text("PrintPDF")
                                .frame(maxWidth: .infinity)
                        })
                        .buttonStyle(.borderedProminent)
                        // The sendDataFile function allows following file extensions:
                        // .bmp, .jpg/.jpeg, .png, .txt, .bin, .dat, .html
                        .fileImporter(isPresented: $isShowPDFFilePicker, allowedContentTypes: [.pdf], allowsMultipleSelection: false, onCompletion: { result in
                            if case .success = result {
                                do {
                                    let file: URL = try result.get().first!
                                    // Get selected file's path from url
                                    printPDFFileURL = file
                                    isShowPrintPDFView = true
                                } catch {
                                    printerViewModel.setAlert(error.localizedDescription)
                                }
                            } else {
                                printerViewModel.setAlert("File Import Failed")
                            }
                        })
                        .navigationDestination(isPresented: $isShowPrintPDFView, destination: {
                            PrintPDFView(printerViewModel: printerViewModel, printPDFFileURL: $printPDFFileURL)
                        })

                        NavigationLink(destination: BarcodeView(printerViewModel: printerViewModel), label: {
                            Text("Barcode")
                                .frame(maxWidth: .infinity)
                        })
                        .buttonStyle(.borderedProminent)
                        
                        NavigationLink(destination: TwoDCodeView(printerViewModel: printerViewModel), label: {
                            Text("2DCode")
                                .frame(maxWidth: .infinity)
                        })
                        .buttonStyle(.borderedProminent)
                    }
                    .padding(.horizontal)
                }
                .navigationBarTitle("", displayMode: .inline)
            }
            .navigationViewStyle(.stack)
        }
    }
    
    func sendDataFile(file: URL, dithering: Bool) {
        var dither: Dithering
        if dithering == true {
            dither = .SII_MPM_DITHERING_ERRORDIFFUSION
        } else {
            dither = .SII_MPM_DITHERING_DISABLE
        }
        let filePath = file.path
        PrinterManager.getDispatchQueue().async {
            printerViewModel.showIndicator(true)
            if file.startAccessingSecurityScopedResource() == true {
                _ = PrinterManager.sendDataFile(filePath: filePath, dithering: dither)
                printerViewModel.setAlert(PrinterManager.getResultString())
                file.stopAccessingSecurityScopedResource()
            } else {
                printerViewModel.setAlert("Open File Failed")
            }
            printerViewModel.showIndicator(false)
        }
        sendDataFileURL = URL(fileURLWithPath: "")
        isSendDataFileImageFile = false
    }
}

