//
//  PreferencesView.swift
//  kordophone2
//
//  Created by James Magahern on 8/24/25.
//

import KeychainAccess
import SwiftUI

struct PreferencesView: View
{
    @State var accountSettingsModel = AccountSettings.ViewModel()
    
    var body: some View {
        TabView {
            AccountSettings(model: $accountSettingsModel)
                .tabItem { Label("Account", systemImage: "person.crop.circle") }
        }
        .frame(width: 480.0, height: 300.0)
        .padding(20.0)
    }
}

struct AccountSettings: View
{
    @Binding var model: ViewModel
    
    var body: some View {
        Form {
            Section("Server Settings") {
                TextField("Server", text: $model.serverURL)
            }
            
            Spacer()
                .frame(height: 44.0)
            
            Section("Authentication") {
                TextField("Username", text: $model.username)
                    .textContentType(.username)
                
                SecureField("Password", text: $model.password)
                    .textContentType(.password)
            }
        }
        
        .task { await model.load() }
    }
    
    // MARK: - Types
    
    @Observable
    class ViewModel
    {
        var serverURL: String
        var username: String
        var password: String
        
        private let xpc = XPCClient()
        private let keychain = Keychain(service: "net.buzzert.kordophonecd")
        
        init(serverURL: String = "", username: String = "", password: String = "") {
            self.serverURL = serverURL
            self.username = username
            self.password = password
            
            autosave()
        }
        
        func load() async {
            do {
                let settings = try await xpc.getSettings()
                self.serverURL = settings.serverUrl
                self.username = settings.username
                self.password = keychain[settings.username] ?? ""
            } catch {
                print("Error getting settings: \(error)")
            }
        }
        
        private func autosave() {
            withObservationTracking {
                _ = serverURL
                _ = username
                _ = password
            } onChange: {
                Task { @MainActor [weak self] in
                    guard let self else { return }
                    
                    do {
                        let currentSettings = try await xpc.getSettings()
                        
                        if currentSettings.serverUrl != serverURL || currentSettings.username != username {
                            try await xpc.setSettings(settings: Serialized.Settings(
                                serverUrl: serverURL,
                                username: username
                            ))
                        }
                        
                        keychain[username] = password
                    } catch {
                        print("Error saving settings: \(error)")
                    }
                    
                    autosave()
                }
            }
        }
    }
}
