import SwiftUI
import CryptoKit

struct SingleKeyView: View {

    @State
    private var needRefresh = false

    let keyManager: KeyManagement
    
    @State
    private var showEditWindow = false
    
    @State
    private var keyText = ""

    let type: KeyManagement.KeyType

    private var generateText: String {
        hasKey ? "Regenerate" : "Generate"
    }

    var hasKey: Bool {
        keyManager.has(type)
    }

    var content: String {
        keyManager.get(type)?.displayString ?? "-"
    }

    var copyText: String {
        guard let key = keyManager.get(type)?.data else {
            return ""
        }
        guard type.usesHashing else {
            return key.hexEncoded
        }
        return SHA256.hash(data: key).hexEncoded
    }

    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            Text(type.displayName)
                .bold()
            Text(needRefresh ? content : content)
                .font(.system(.body, design: .monospaced))
                .foregroundColor(.secondary)
            HStack() {
                Button(generateText) {
                    keyManager.generate(type)
                    needRefresh.toggle()
                }
                .padding([.horizontal, .bottom])
                .padding(.top, 4)

                Button(type.usesHashing ? "Copy hash" : "Copy") {
                    UIPasteboard.general.string = copyText
                }
                .disabled(!hasKey)
                .padding([.horizontal, .bottom])
                .padding(.top, 4)
                Button("Edit") {
                    keyText = keyManager.get(type)?.displayString ?? ""
                    print("Set key text to '\(keyText)'")
                    showEditWindow = true
                }
                .padding([.horizontal, .bottom])
                .padding(.top, 4)
                Spacer()
            }
        }
        .alert("Update key", isPresented: $showEditWindow, actions: {
            TextField("Key data", text: $keyText)
                .lineLimit(4)
                .font(.system(.body, design: .monospaced))
                .foregroundColor(.primary)
            Button("Save", action: saveKey)
            Button("Cancel", role: .cancel, action: {})
        }, message: {
            Text("Enter the hex encoded key")
        })
    }
    
    private func saveKey() {
        let cleanText = keyText.replacingOccurrences(of: " ", with: "")
        guard let keyData = Data(fromHexEncodedString: cleanText) else {
            print("Invalid key string")
            return
        }
        let keyLength = type.keyLength.bitCount
        guard keyData.count * 8 == keyLength else {
            print("Invalid key length \(keyData.count * 8) bits, expected \(keyLength)")
            return
        }
        keyManager.save(type, data: keyData)
        print("Key \(type) saved")
    }
}

struct SingleKeyView_Previews: PreviewProvider {
    static var previews: some View {
        SingleKeyView(
            keyManager: KeyManagement(),
            type: .deviceKey)
        .previewLayout(.fixed(width: 350, height: 100))
    }
}
