//
//  PrinterListView.swift
//  SIIMpaPrinterSample
//

import SwiftUI
import SIIMpaPrinterManager

struct PrinterListView: View {
    @ObservedObject var printerViewModel: PrinterViewModel
    @Binding var isShowPrinterListView: Bool
    @State var printerList : [SiiPrinter] = []
    @State var isDiscoveryComplete: Bool = true
    @Environment(\.dismiss) var dismiss
    var body: some View {
        ZStack {
            VStack {
                HStack { // Header of sheet
                    Button("close") {
                        dismiss()
                    }
                    Spacer()
                    
                    // refresh button
                    Button(action: {
                        searchPrinter()
                    }, label: {
                        Image(systemName: "arrow.triangle.2.circlepath")
                            .resizable()
                            .scaledToFill()
                            .aspectRatio(contentMode: .fit)
                            .frame(width: 20, height: 20)
                            .padding(5)
                    })
                }
                .padding()
                
                List {
                    ForEach(printerList) { foundPrinter in
                        HStack { // Printer cells
                            VStack(alignment: .leading) {
                                Text(foundPrinter.address)
                                HStack {
                                    Text(foundPrinter.portType)
                                        .font(.footnote)
                                    Text(foundPrinter.modelName)
                                        .font(.footnote)
                                }
                            }
                            Spacer()
                        }
                        .padding(1)
                        .contentShape(RoundedRectangle(cornerRadius: 5))
                        .onTapGesture {
                            // Set selected printer to viewModel and back to main view
                            printerViewModel.savePrinterInfo(printer: foundPrinter)
                            printerViewModel.setPrinter(printer: foundPrinter)
                            dismiss()
                        }
                    }
                }
                .listStyle(.plain)
            }
            if printerViewModel.isShowPrinterListViewIndicator == true {
                PrinterListLoadingView(printerViewModel: printerViewModel)
            }
        }
        .onAppear {
            // Start printer discovery when sheet appears
            searchPrinter()
        }
        .onDisappear() {
            // Cancel printer discovery immediately and clear printerList when sheet disappears
            DiscoverManager.cancelDiscoveryTcpPrinter()
            isShowPrinterListView = false
            printerList = []
        }
    }
    
    /// Printer discovery process
    func searchPrinter() {
        printerList = []
        printerViewModel.showPrinterListViewIndicator(true)
        DiscoverManager.getDispatchQueue().async {
            searchBluetoothPrinter()
            searchTcpPrinter()
            printerViewModel.showPrinterListViewIndicator(false)
        }
    }
    
    /// Bluetooth printer discovery process
    func searchBluetoothPrinter() {
        var foundPrinterList: [SIIMpaDiscoveredPrinter] = []
        DiscoverManager.startDiscoveryBluetoothPrinter()
        foundPrinterList = DiscoverManager.getFoundPrinter()
        if foundPrinterList.count > 0 {
            for foundPrinter in foundPrinterList {
                var btPrinter = SiiPrinter()
                btPrinter.address = foundPrinter.bluetoothAddress
                btPrinter.modelName = foundPrinter.printerModel
                btPrinter.portType = PORTTYPE_BLUETOOTH
                printerList.append(btPrinter)
            }
        }
    }
    
    /// Tcp printer discovery process
    func searchTcpPrinter() {
        var foundPrinterList: [SIIMpaDiscoveredPrinter] = []
        DiscoverManager.startDiscoveryTcpPrinter()
        while DiscoverManager.discoverFinished() != true {
            foundPrinterList = DiscoverManager.getFoundPrinter()
            if foundPrinterList.count > 0 {
                for foundPrinter in foundPrinterList {
                    var tcpPrinter = SiiPrinter()
                    tcpPrinter.address = foundPrinter.ipAddress
                    tcpPrinter.modelName = foundPrinter.printerModel
                    tcpPrinter.portType = PORTTYPE_TCP_IP
                    
                    if printerList.count > 0 {
                        var isPrinterExist: Bool = false
                        for existPrinter in printerList {
                            if foundPrinter.ipAddress == existPrinter.address {
                                isPrinterExist = true
                                break
                            }
                        }
                        if isPrinterExist == false {
                            printerList.append(tcpPrinter)
                        }
                    }
                    else {
                        printerList.append(tcpPrinter)
                    }
                }
            }
            Thread.sleep(forTimeInterval: 0.01)
        }
    }
}
