//
//  NetworkView.swift
//  punchnet
//
//  Created by 安礼成 on 2026/1/16.
//

import SwiftUI

// 连接状态
enum ConnectState {
    case waitAuth
    case connected
    case disconnected
}

struct NetworkView: View {
    @Environment(UserContext.self) var userContext: UserContext
    @Environment(\.openWindow) private var openWindow
    @State private var networkModel = NetworkModel()
    @State private var showMode: ShowMode = .resource
    // 状态管理
    @State private var connectState: ConnectState = .disconnected
    @State private var isOn: Bool = false
    @State private var vpnManager: VPNManager = VPNManager.shared

    // 展示状态
    enum ShowMode {
        case resource
        case device
    }
    
    var body: some View {
        VStack {
            HStack {
                
                VStack {
                    HStack(alignment: .center) {
                        Text(userContext.networkSession?.networkName ?? "未知")
                        Text(">")
                        Spacer()
                    }
                    
                    HStack {
                        Toggle("", isOn: $isOn)
                            .toggleStyle(SwitchToggleStyle(tint: .green))
                            .disabled(true)
                        
                        Text("已连接")
                        
                        Spacer()
                    }
                }
                .frame(width: 320)
                
                if self.connectState == .connected {
                    // 显示设备和资源选项
                    HStack {
                        Button {
                            self.showMode = .resource
                        } label: {
                            Text("资源")
                        }
                        
                        Button {
                            self.showMode = .device
                        } label: {
                            Text("设备")
                        }
                    }
                }
                Spacer()
            }
            
            Group {
                switch self.connectState {
                case .waitAuth:
                    NetworkWaitAuthView(networkModel: self.networkModel)
                case .connected:
                    Group {
                        switch self.showMode {
                        case .resource:
                            NetworkResourceGroupView(networkModel: self.networkModel)
                        case .device:
                            NetworkDeviceGroupView(networkModel: self.networkModel)
                        }
                    }
                case .disconnected:
                    NetworkDisconnctedView(networkModel: self.networkModel)
                }
            }
            
            Spacer()
        }
        .padding(.top, 10)
        .padding(.leading, 10)
        .onChange(of: vpnManager.vpnStatus) { _, newState in
            NSLog("print view change: \(newState)")
            switch newState {
            case .connected:
                self.connectState = .connected
                self.isOn = true
            case .disconnected:
                self.connectState = .disconnected
                self.isOn = false
            }
        }
        .toolbar {
            if self.connectState == .connected {
                ToolbarItem(placement: .primaryAction) {
                    Button {
                        openWindow(id: "settings")
                    } label: {
                        Image(systemName: "gearshape")
                    }
                }
            }
        }
    }
}

// 网络处于未连接状态
struct NetworkDisconnctedView: View {
    @Bindable var networkModel: NetworkModel
    @Environment(AppContext.self) var appContext: AppContext
    @Environment(UserContext.self) var userContext: UserContext
    
    @State private var showAlert = false
    @State private var errorMessage = ""

    var body: some View {
        ZStack {
            Color.clear
            
            VStack {
                Button {
                    Task { @MainActor in
                        do {
                            try await self.connect()
                            try await self.startVpn()
                        } catch let err {
                            self.showAlert = true
                            self.errorMessage = err.localizedDescription
                        }
                    }
                } label: {
                    Text("连接")
                        .font(.system(size: 14, weight: .regular))
                        .padding([.top, .bottom], 8)
                        .padding([.leading, .trailing], 30)
                        .foregroundColor(.white)
                    
                }
                .background(Color(red: 74/255, green: 207/255, blue: 154/255))
                .cornerRadius(5)
                .frame(width: 120, height: 35)
                
                Button {
                    Task {
                        try await VPNManager.shared.disableVpn()
                    }
                } label: {
                    Text("关闭")
                        .font(.system(size: 14, weight: .regular))
                        .padding([.top, .bottom], 8)
                        .padding([.leading, .trailing], 30)
                        .foregroundColor(.white)
                    
                }
                .background(Color(red: 74/255, green: 207/255, blue: 154/255))
                .cornerRadius(5)
                .frame(width: 120, height: 35)
            }
        }
        .alert(isPresented: $showAlert) {
            Alert(title: Text("提示"), message: Text(self.errorMessage))
        }
        
    }
    
    private func connect() async throws {
        guard let networkSession = userContext.networkSession else {
            return
        }
        try await networkModel.connect(networkSession: networkSession)
    }
    
    // 执行登陆操作
    private func startVpn() async throws {
        guard let networkSession = userContext.networkSession else {
            return
        }
        
        let networkContext = networkModel.networkContext
        let options = SystemConfig.getOptions(networkId: UInt32(networkSession.networkId),
                                              networkDomain: networkSession.networkDomain,
                                              ip: networkContext.ip,
                                              maskLen: networkContext.maskLen,
                                              accessToken: networkSession.accessToken,
                                              identityId: networkContext.identityId,
                                              hostname: networkContext.hostname,
                                              noticePort: self.appContext.noticePort)
        // token存在则优先使用token
        try await VPNManager.shared.enableVpn(options: options!)
    }
    
}

// 网络处于连接状态

// 显示资源信息
struct NetworkResourceGroupView: View {
    @Bindable var networkModel: NetworkModel
    
    var body: some View {
        LazyVGrid(columns: Array(repeating: GridItem(.flexible()), count: 3), spacing: 8) {
            ForEach(self.networkModel.networkContext.resourceList, id: \.id) { resource in
                NetworkResourceView(resource: resource)
            }
        }
    }
}

struct NetworkResourceView: View {
    var resource: Resource
    
    var body: some View {
        VStack {
            HStack {
                Text(resource.connectionStatus)
                
                Text(resource.name)
                    .font(.system(size: 14, weight: .regular))
            }
            
            Text(resource.url)
                .font(.system(size: 14, weight: .regular))
                .padding(.leading, 30)
            
        }
    }
}

// 显示设备信息
struct NetworkDeviceGroupView: View {
    @Bindable var networkModel: NetworkModel
    @State private var selectedId: Int?
    
    var body: some View {
        NavigationSplitView {
            List(self.networkModel.networkContext.nodeList, id: \.id, selection: $selectedId) { node in
                NetworkNodeHeadView(node: node)
            }
            .listStyle(.sidebar)
            .onChange(of: selectedId) {
                self.networkModel.changeSelectedNode(nodeId: selectedId)
            }
            .onAppear {
                if selectedId == nil {
                    selectedId = self.networkModel.networkContext.nodeList.first?.id
                }
            }
        } detail: {
            NetworkNodeDetailView(node: networkModel.selectedNode)
        }
    }
    
}

struct NetworkNodeHeadView: View {
    var node: Node
    
    var body: some View {
        VStack {
            HStack {
                Text(node.connectionStatus)
                
                Text(node.name)
                    .font(.system(size: 14, weight: .regular))
            }
            
            Text(node.ip)
                .font(.system(size: 14, weight: .regular))
                .padding(.leading, 30)
        }
    }
}

struct NetworkNodeDetailView: View {
    @Environment(UserContext.self) var userContext: UserContext
    var node: Node?
    @State private var resources: [Resource] = []

    var body: some View {
        Group {
            if let node {
                List {
                    Section {
                        HStack {
                            Text("连接状态")
                            Text("\(node.connectionStatus)")
                            Spacer()
                        }
                        
                        HStack {
                            Text("虚拟IPv4")
                            Text("\(node.ip)")
                            Spacer()
                        }
                        
                        HStack {
                            Text("操作系统")
                            Text(node.system ?? "未知")
                            Spacer()
                        }
                    }
                    
                    Section("服务列表") {
                        ForEach(resources, id: \.id) { resource in
                            HStack {
                                Text("\(resource.name)")
                                Text("\(resource.url)")
                            }
                        }
                    }
                }
                .task(id: node.id) {
                    await self.loadNodeResources(id: node.id)
                }
            } else {
                EmptyView()
            }
        }
    }
    
    private func loadNodeResources(id: Int) async {
        guard let networkSession = userContext.networkSession else {
            return
        }
        
        let params: [String: Any] = [
            "client_id": SystemConfig.getClientId(),
            "access_token": networkSession.accessToken,
            "id": id
        ]
        
        if let nodeDetail = try? await SDLAPIClient.doPost(path: "/get_node_resources", params: params, as: NodeDetail.self) {
            self.resources = nodeDetail.resourceList
        }
    }
}

struct NetworkWaitAuthView: View {
    @Bindable var networkModel: NetworkModel
    
    var body: some View {
        Color.clear
            .overlay {
                Text("等待确认中")
            }
    }
}

#Preview {
    NetworkView()
}
