//
//  NetworkView.swift
//  punchnet
import SwiftUI
import Observation

// MARK: - 基础模型协议
enum ConnectState {
    case waitAuth, connected, disconnected
}

// MARK: - 主网络视图
struct NetworkView: View {
    @Environment(UserContext.self) var userContext
    @Environment(AppContext.self) var appContext
    @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 isConnecting: Bool = false

    private var vpnManager = VPNManager.shared

    enum ShowMode: String, CaseIterable {
        case resource = "访问资源"
        case device = "成员设备"
    }
    
    var body: some View {
        VStack(spacing: 0) {
            // 1. 头部区域 (Header)
            headerSection
            
            Divider()
            
            // 2. 内容区域 (Content)
            Group {
                switch connectState {
                case .waitAuth:
                    NetworkWaitAuthView(networkModel: networkModel)
                case .connected:
                    connectedContent
                case .disconnected:
                    disconnectedContent
                }
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .background(VisualEffectView(material: .windowBackground, blendingMode: .behindWindow))
        }
        .frame(minWidth: 700, minHeight: 500) // 适当调大宽度以适应 SplitView
        .onAppear {
            syncState(vpnManager.vpnStatus)
        }
        .onChange(of: vpnManager.vpnStatus) { _, newStatus in
            withAnimation(.snappy) {
                syncState(newStatus)
            }
        }
    }
}

// MARK: - 视图组件扩展
extension NetworkView {
    
    private var headerSection: some View {
        HStack(spacing: 16) {
            statusIndicator
            
            VStack(alignment: .leading, spacing: 2) {
                Text(userContext.networkSession?.networkName ?? "未连接网络")
                    .font(.system(size: 14, weight: .semibold))
                
                if connectState == .connected {
                    Text("虚拟局域网 IP: \(networkModel.networkContext.ip)")
                        .font(.system(size: 11, design: .monospaced))
                        .foregroundColor(.secondary)
                } else {
                    Text("PunchNet 服务未就绪")
                        .font(.caption)
                        .foregroundColor(.secondary)
                }
            }
            
            Spacer()
            
            if connectState == .connected {
                Picker("", selection: $showMode) {
                    ForEach(ShowMode.allCases, id: \.self) {
                        Text($0.rawValue).tag($0)
                    }
                }
                .pickerStyle(.segmented)
                .frame(width: 160)
            }
            
            Button {
                openWindow(id: "settings")
            } label: {
                Image(systemName: "slider.horizontal.3")
                    .font(.system(size: 14))
                    .foregroundColor(.secondary)
            }
            .buttonStyle(.plain)
            .help("配置中心")
        }
        .padding(.horizontal, 20)
        .padding(.vertical, 14)
        .background(VisualEffectView(material: .headerView, blendingMode: .withinWindow))
    }
    
    private var statusIndicator: some View {
        ZStack {
            Circle()
                .fill(connectState == .connected ? Color.green.opacity(0.15) : Color.primary.opacity(0.05))
                .frame(width: 36, height: 36)
            
            Image(systemName: connectState == .connected ? "checkmark.shield.fill" : "shield.slash.fill")
                .symbolRenderingMode(.hierarchical)
                .foregroundStyle(connectState == .connected ? Color.green : Color.secondary)
                .font(.system(size: 16))
        }
    }
    
    @ViewBuilder
    private var connectedContent: some View {
        if showMode == .resource {
            // 资源视图：网格布局
            ScrollView {
                LazyVGrid(columns: [
                    GridItem(.flexible(), spacing: 8),
                    GridItem(.flexible(), spacing: 8),
                    GridItem(.flexible(), spacing: 8)
                ], spacing: 10) {
                    ForEach(networkModel.networkContext.resourceList, id: \.uuid) { res in
                        ResourceItemCard(resource: res)
                    }
                }
                .padding(20)
            }
            .transition(.opacity)
            .frame(maxWidth: .infinity)
        } else {
            // 设备视图：双栏布局
            NetworkDeviceGroupView(networkModel: networkModel)
                .transition(.asymmetric(insertion: .move(edge: .trailing), removal: .opacity))
        }
    }
    
    private var disconnectedContent: some View {
        VStack(spacing: 20) {
            Spacer()
            Image(systemName: "antenna.radiowaves.left.and.right")
                .font(.system(size: 40, weight: .ultraLight))
                .foregroundStyle(.tertiary)
                .symbolEffect(.pulse, options: .repeating)
            
            Text("尚未接入网络")
                .font(.headline)
            
            Button(action: { startConnection() }) {
                if isConnecting {
                    ProgressView()
                        .controlSize(.small)
                        .frame(width: 80)
                } else {
                    Text("建立安全连接")
                        .frame(width: 80)
                }
            }
            .buttonStyle(.borderedProminent)
            .disabled(isConnecting)
            Spacer()
        }
    }
    
    private func syncState(_ status: VPNManager.VPNStatus) {
        switch status {
        case .connected: connectState = .connected
        case .disconnected: connectState = .disconnected
        @unknown default: connectState = .disconnected
        }
    }
    
    private func startConnection() {
        isConnecting = true
        Task {
            do {
                guard let session = userContext.networkSession else {
                    return
                }
                
                let context = try await networkModel.connect(networkSession: session)
                
                // 登陆后需要保存到app的上线文
                self.appContext.networkContext = context
                
                if let options = SystemConfig.getOptions(
                    networkId: UInt32(session.networkId),
                    networkDomain: session.networkDomain,
                    ip: context.ip,
                    maskLen: context.maskLen,
                    accessToken: session.accessToken,
                    identityId: context.identityId,
                    hostname: context.hostname,
                    noticePort: appContext.noticePort
                ) {
                    try await vpnManager.enableVpn(options: options)
                }
            } catch {
                print("Connection error: \(error)")
            }
            
            await MainActor.run {
                isConnecting = false
            }
        }
    }
}

// MARK: - 设备组视图 (NavigationSplitView)
struct NetworkDeviceGroupView: View {
    @Bindable var networkModel: NetworkModel
    @State private var selectedId: Int?
    
    var body: some View {
        NavigationSplitView {
            List(networkModel.networkContext.nodeList, id: \.id, selection: $selectedId) { node in
                NetworkNodeHeadView(node: node)
                    .tag(node.id)
            }
            .listStyle(.sidebar)
            .navigationSplitViewColumnWidth(min: 200, ideal: 220)
        } detail: {
            if let selectedNode = networkModel.networkContext.nodeList.first(where: { $0.id == selectedId }) {
                NetworkNodeDetailView(node: selectedNode)
            } else {
                ContentUnavailableView("选择成员设备", systemImage: "macbook.and.iphone", description: Text("查看详细网络信息和服务"))
            }
        }
        .onAppear {
            if selectedId == nil {
                selectedId = networkModel.networkContext.nodeList.first?.id
            }
        }
    }
}

// MARK: - 子组件
struct NetworkNodeHeadView: View {
    var node: Node
    var body: some View {
        HStack(spacing: 10) {
            Circle()
                .fill(node.connectionStatus == "在线" ? Color.green : Color.secondary.opacity(0.4))
                .frame(width: 8, height: 8)
            
            VStack(alignment: .leading, spacing: 2) {
                Text(node.name)
                    .font(.system(size: 13, weight: .medium))
                
                Text(node.ip)
                    .font(.system(size: 11, design: .monospaced))
                    .foregroundColor(.secondary)
            }
        }
        .padding(.vertical, 4)
    }
}

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

    var body: some View {
        List {
            Section("节点信息") {
                LabeledContent("连接状态", value: node.connectionStatus)
                LabeledContent("虚拟IPv4", value: node.ip)
                LabeledContent("系统环境", value: node.system ?? "未知")
            }
            
            Section("提供的服务") {
                if isLoading {
                    ProgressView()
                        .controlSize(.small)
                } else if resources.isEmpty {
                    Text("该节点暂未发布资源")
                        .foregroundColor(.secondary)
                        .font(.callout)
                } else {
                    ForEach(resources, id: \.id) { res in
                        VStack(alignment: .leading) {
                            Text(res.name)
                                .font(.body)
                            
                            Text(res.url)
                                .font(.caption)
                                .foregroundColor(.secondary)
                        }
                    }
                }
            }
        }
        .task(id: node.id) {
            await loadNodeResources(id: node.id)
        }
    }
    
    private func loadNodeResources(id: Int) async {
        guard let session = userContext.networkSession else {
            return
        }
        
        isLoading = true
        defer {
            isLoading = false
        }
        
        let params: [String: Any] = [
            "client_id": SystemConfig.getClientId(),
            "access_token": session.accessToken,
            "id": id
        ]
        
        if let detail = try? await SDLAPIClient.doPost(path: "/get_node_resources", params: params, as: NodeDetail.self) {
            self.resources = detail.resourceList
        }
    }
}

struct ResourceItemCard: View {
    let resource: Resource
    @State private var isHovered = false
    
    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            Image(systemName: "safari.fill")
                .foregroundColor(.accentColor)
                .font(.title3)
            
            Text(resource.name)
                .font(.headline)
                .lineLimit(1)
                .truncationMode(.tail)
            
            Text(resource.url)
                .font(.caption2)
                .foregroundColor(.secondary)
                .lineLimit(1)
                .truncationMode(.middle)
        }
        .padding()
        .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
        .overlay(
            RoundedRectangle(cornerRadius: 10)
                .stroke(Color.gray, lineWidth: 1)
        )
        .background(
            RoundedRectangle(cornerRadius: 10)
                    .fill(Color(isHovered ? NSColor.selectedControlColor : NSColor.controlBackgroundColor))
        )
        .onHover {
            isHovered = $0
        }
    }
}

struct NetworkWaitAuthView: View {
    @Bindable var networkModel: NetworkModel
    
    var body: some View {
        VStack(spacing: 16) {
            ProgressView()
            
            Text("等待认证确认中...")
                .foregroundColor(.secondary)
        }
    }
}
