//
//  PrintPDFView.swift
//  SIIMpaPrinterSample
//

import SwiftUI
import SIIMpaPrinterManager

struct PrintPDFView: View {
    @ObservedObject var printerViewModel: PrinterViewModel
    @Binding var printPDFFileURL: URL

    @FocusState var isKeyboardActive: Bool
    private enum PagesControl: String, CaseIterable, Identifiable {
            case allPages = "All"
            case partPages = "Pages"
            var id: String { rawValue }
        }
    @State private var printPagesControl = PagesControl.allPages

    private enum WidthControl: String, CaseIterable, Identifiable {
            case pdfWidth = "PDF Width"
            case userWidth = "User Specify"
            var id: String { rawValue }
        }
    @State private var printWidthControl = WidthControl.pdfWidth

    private enum BottomMarginControl: String, CaseIterable, Identifiable {
            case pdfBottomMargin = "PDF Margin"
            case userBottomMargin = "User Specify"
            var id: String { rawValue }
        }
    @State private var printBottomMarginControl = BottomMarginControl.pdfBottomMargin

    @State var startIndexStr: String = "1"
    @State var endIndexStr: String = "100"
    @State var widthStr: String = "832"
    @State var bottomMarginStr: String = "0"
    @State var rotationStr: String = PDF_ROTATION_NONE
    @State var ditheringStr: String = PDF_DITHERING_ERROR_DIFFUSION
    var body: some View {
        VStack {
            List {
                VStack(alignment: .leading) {
                    Text("Pages to print")
                        .bold()
                    Picker("Pages to print", selection: $printPagesControl) {
                        ForEach(PagesControl.allCases) {
                            Text($0.rawValue).tag($0)
                        }
                    }
                    .pickerStyle(.segmented)

                    // When "Pages to print" segment is selected to "Pages", show textField for startIndex and endIndex input.
                    if (printPagesControl == PagesControl.partPages) {
                        HStack {
                            TextField(PDF_START_INDEX_SECTION, text: $startIndexStr)
                                .keyboardType(.numberPad)
                                .focused($isKeyboardActive)
                        Spacer()
                        Text("~")
                        Spacer()
                            TextField(PDF_END_INDEX_SECTION, text: $endIndexStr)
                                .keyboardType(.numberPad)
                                .focused($isKeyboardActive)
                        }
                    }
                }

                VStack(alignment: .leading) {
                    Text(PDF_ROTATION_SECTION)
                        .bold()
                    NavigationLink(rotationStr, destination: SetValueView(printerViewModel: printerViewModel, value: $rotationStr)
                        .onAppear() {
                            printerViewModel.setValueTable(title: PDF_ROTATION_SECTION, valueTable: PDF_ROTATION_TABLE)
                        })
                }

                VStack(alignment: .leading) {
                    Text(PDF_WIDTH_SECTION)
                        .bold()
                    Picker(PDF_WIDTH_SECTION, selection: $printWidthControl) {
                        ForEach(WidthControl.allCases) {
                            Text($0.rawValue).tag($0)
                        }
                    }
                    .pickerStyle(.segmented)

                    // When "Width" segment is selected to "User Specify", show textField for width input.
                    if (printWidthControl == WidthControl.userWidth) {
                        TextField(PDF_WIDTH_SECTION, text: $widthStr)
                            .frame(maxWidth: .infinity)
                            .keyboardType(.numberPad)
                            .focused($isKeyboardActive)
                    }
                }

                VStack(alignment: .leading) {
                    Text(PDF_BOTTOM_MARGIN_SECTION)
                        .bold()
                    Picker(PDF_BOTTOM_MARGIN_SECTION, selection: $printBottomMarginControl) {
                        ForEach(BottomMarginControl.allCases) {
                            Text($0.rawValue).tag($0)
                        }
                    }
                    .pickerStyle(.segmented)

                    // When "Bottom Margin" segment is selected to "User Specify", show textField for bottomMargin input.
                    if (printBottomMarginControl == BottomMarginControl.userBottomMargin) {
                        TextField(PDF_BOTTOM_MARGIN_SECTION, text: $bottomMarginStr)
                            .frame(maxWidth: .infinity)
                            .keyboardType(.numberPad)
                            .focused($isKeyboardActive)
                    }
                }

                VStack(alignment: .leading) {
                    Text(PDF_DITHERING_SECTION)
                        .bold()
                    NavigationLink(ditheringStr, destination: SetValueView(printerViewModel: printerViewModel, value: $ditheringStr)
                        .onAppear() {
                            printerViewModel.setValueTable(title: PDF_DITHERING_SECTION, valueTable: PDF_DITHERING_TABLE)
                        })
                }
            }
            .listStyle(.plain)
            .toolbar {
                ToolbarItemGroup(placement: .keyboard, content: {
                    Spacer()
                    Button("close") {
                        isKeyboardActive = false
                        checkValueValid()
                    }
                })
            }
            Spacer()
        }
        .navigationTitle("Print PDF")
        .navigationBarItems(trailing:
                                HStack {
            Button("Print") {
                var startIndex: Int = -1
                var endIndex: Int = -1
                var width: Int = 832
                var bottomMargin: Int = -1
                let rotation: Rotate = rotationStr == PDF_ROTATION_NONE ? .SII_MPM_ROTATE_NONE : .SII_MPM_ROTATE_180
                let dithering: Dithering = ditheringStr == PDF_DITHERING_DISABLE ? .SII_MPM_DITHERING_DISABLE : .SII_MPM_DITHERING_ERRORDIFFUSION

                if (printPagesControl == .allPages) {
                    // When "Pages to print" segment is selected to "All", print all pages of PDF file.
                    // When startIndex is specified to -1, the value of endIndex is ignored.
                    startIndex = -1
                    endIndex = -1
                } else {
                    startIndex = Int(startIndexStr) ?? 1
                    endIndex = Int(endIndexStr) ?? 100
                }
                switch printWidthControl {
                case .pdfWidth:
                    // When "Width" segment is selected to "PDF Width", file is printed as its original width.
                    width = -1
                case .userWidth:
                    width = Int(widthStr) ?? 832
                }
                switch printBottomMarginControl {
                case .pdfBottomMargin:
                    // When "BottomMargin" segment is selected to "PDF Margin", file is printed as its original bottom margin.
                    bottomMargin = -1
                case .userBottomMargin:
                    bottomMargin = Int(bottomMarginStr) ?? 0
                }

                let filePath = printPDFFileURL.path
                PrinterManager.getDispatchQueue().async {
                    printerViewModel.showIndicator(true)
                    if printPDFFileURL.startAccessingSecurityScopedResource() == true {
                        // Example of printing a PDF file:
                        // To print all pages of a PDF file, set “startIndex” to -1.
                        // To print pages 2 through 5, specify 2 for “startIndex” and 5 for “endIndex”.
                        _ = PrinterManager.printPDF(filePath: filePath, startIndex: startIndex, endIndex: endIndex, rotate: rotation, width: width, bottomMargin: bottomMargin, dithering: dithering)
                        printerViewModel.setAlert(PrinterManager.getResultString())
                        printPDFFileURL.stopAccessingSecurityScopedResource()
                    } else {
                        printerViewModel.setAlert("Open File Failed")
                    }
                    printerViewModel.showIndicator(false)
                }
            }
        })
    }
    func checkValueValid() {
        if Int(startIndexStr) == nil {
            startIndexStr = "1"
        }
        if Int(endIndexStr) == nil {
            endIndexStr = "100"
        }
        if Int(widthStr) == nil {
            widthStr = "832"
        }
        if Int(bottomMarginStr) == nil {
            bottomMarginStr = "0"
        }
    }
}

