//
//  LoginView.swift
//  punchnet
//
//  Created by 安礼成 on 2026/1/15.
//
import SwiftUI
import Observation

// MARK: - 主容器视图
struct LoginView: View {
    @State private var authMethod: AuthMethod = .account
    
    var username: String?
    
    enum AuthMethod: String, CaseIterable {
        case account = "账户登录"
        case token = "密钥认证"
    }
    
    var body: some View {
        ZStack {
            Color.clear
            
            VStack(spacing: 0) {
                // 顶部 Logo 区域
                VStack(spacing: 12) {
                    ZStack {
                        Circle()
                            .fill(Color.accentColor.opacity(0.1))
                            .frame(width: 80, height: 80)
                        
                        Image(systemName: "network") // 建议使用 SF Symbol 保持精致感
                            .font(.system(size: 38, weight: .semibold))
                            .foregroundColor(.accentColor)
                    }
                    
                    Text("PunchNet")
                        .font(.system(size: 24, weight: .bold, design: .rounded))
                        .tracking(1)
                }
                .padding(.top, 40)
                .padding(.bottom, 30)
                
                // 原生分段切换器
                Picker("", selection: $authMethod) {
                    ForEach(AuthMethod.allCases, id: \.self) { method in
                        Text(method.rawValue).tag(method)
                    }
                }
                .pickerStyle(.segmented)
                .frame(width: 220)
                .padding(.bottom, 30)
                
                // 动态内容区
                ZStack {
                    switch authMethod {
                    case .account:
                        LoginAccountView(username: self.username ?? "")
                            .transition(.move(edge: .leading).combined(with: .opacity))
                    case .token:
                        LoginTokenView()
                            .transition(.move(edge: .trailing).combined(with: .opacity))
                    }
                }
                .animation(.spring(response: 0.3, dampingFraction: 0.8), value: authMethod)
                .frame(height: 180)
                
                Spacer()
                
                // 底部页脚
                HStack(spacing: 4) {
                    Circle()
                        .fill(Color.green)
                        .frame(width: 8, height: 8)
                    
                    Text("服务状态正常")
                        .font(.system(size: 11))
                        .foregroundColor(.secondary)
                }
                .padding(.bottom, 20)
            }
        }
    }
    
}

// MARK: - 账户登录组件
struct LoginAccountView: View {
    @Environment(AppContext.self) var appContext: AppContext
    
    @State var username: String = ""
    @State private var password: String = ""
    @State private var isLoading = false
    
    // 错误提示
    @State private var showAlert: Bool = false
    @State private var errorMessage: String = ""
    
    var body: some View {
        VStack(spacing: 16) {
            VStack(alignment: .leading, spacing: 12) {
                // 标准圆角输入框
                CustomTextField(title: "手机号/邮箱", text: $username, icon: "person.fill")
                
                VStack(alignment: .trailing, spacing: 4) {
                    CustomSecureField(title: "密码", text: $password, icon: "lock.fill")
                    
                    HStack {
                        Button("注册") {
                            withAnimation(.spring(duration: 0.6, bounce: 0.2)) {
                                self.appContext.appScene = .register
                            }
                        }
                        .buttonStyle(.link)
                        .font(.system(size: 11))
                        .foregroundColor(.secondary)
                        
                        Button("忘记密码？") {
                            withAnimation(.spring(duration: 0.6, bounce: 0.2)) {
                                self.appContext.appScene = .resetPassword
                            }
                        }
                        .buttonStyle(.link)
                        .font(.system(size: 11))
                        .foregroundColor(.secondary)
                    }
                }
            }
            .frame(width: 280)
            
            // 蓝色主按钮
            Button(action: {
                Task { @MainActor in
                   await self.login()
                }
            }) {
                HStack {
                    if isLoading {
                        ProgressView()
                            .controlSize(.small)
                            .padding(.trailing, 4)
                    }
                    
                    Text("登录网络")
                        .fontWeight(.medium)
                }
                .frame(maxWidth: .infinity)
            }
            .buttonStyle(.borderedProminent)
            .controlSize(.large)
            .frame(width: 280)
            .keyboardShortcut(.defaultAction) // 绑定回车键
            .disabled(username.isEmpty || password.isEmpty || isLoading)
        }
        .alert(isPresented: $showAlert) {
            Alert(title: Text("提示"), message: Text(self.errorMessage))
        }
        .onAppear {
            if let (cacheUsername, cachePassword) = self.appContext.loadCacheUsernameAndPassword() {
                self.username = cacheUsername
                self.password = cachePassword
            }
        }
    }
    
    private func login() async {
        self.isLoading = true
        defer {
            self.isLoading = false
        }
        
        do {
            _ = try await appContext.loginWith(username: username, password: password)
            withAnimation(.spring(duration: 0.6, bounce: 0.2)) {
                self.appContext.appScene = .logined
            }
            
        } catch let err as SDLAPIError {
            self.showAlert = true
            self.errorMessage = err.message
        } catch let err {
            self.showAlert = true
            self.errorMessage = err.localizedDescription
        }
    }
}

// MARK: - 密钥登录组件
struct LoginTokenView: View {
    @Environment(AppContext.self) var appContext: AppContext

    @State private var token = ""
    @State private var tokenHistory: [TokenHistoryItem] = []
    @State private var wantsTokenHistory = false
    @State private var showTokenHistory = false
    @State private var isLoading = false
    @FocusState private var isTokenFocused: Bool
    
    // 错误提示
    @State private var showAlert: Bool = false
    @State private var errorMessage: String = ""

    private var normalizedToken: String {
        token.trimmingCharacters(in: .whitespacesAndNewlines)
    }

    private var visibleTokenHistory: [TokenHistoryItem] {
        guard !normalizedToken.isEmpty else {
            return tokenHistory
        }

        let matchedItems = tokenHistory.filter {
            $0.token.localizedCaseInsensitiveContains(normalizedToken)
                || ($0.networkName?.localizedCaseInsensitiveContains(normalizedToken) == true)
        }

        return matchedItems
    }

    private var tokenHistoryPopoverBinding: Binding<Bool> {
        Binding(
            get: {
                showTokenHistory
            },
            set: { isPresented in
                showTokenHistory = isPresented
                if !isPresented {
                    wantsTokenHistory = false
                }
            }
        )
    }

    var body: some View {
        VStack(spacing: 20) {
            tokenInputField
            
            Button(action: {
                Task { @MainActor in
                    await self.login()
                }
            }) {
                Text("验证并连接")
                    .fontWeight(.medium)
                    .frame(maxWidth: .infinity)
            }
            .buttonStyle(.borderedProminent)
            .controlSize(.large)
            .frame(width: 280)
            .disabled(normalizedToken.isEmpty || isLoading)
        }
        .alert(isPresented: $showAlert) {
            Alert(title: Text("提示"), message: Text(self.errorMessage))
        }
        .onAppear {
            self.tokenHistory = self.appContext.loadCacheTokenHistory()
            if let cacheToken = self.appContext.loadCacheToken() {
                self.token = cacheToken
            }
        }
    }

    private var tokenInputField: some View {
        HStack {
            Image(systemName: "key.fill")
                .foregroundColor(.secondary)
                .frame(width: 20)

            TextField("请输入认证密钥 (Token)", text: $token)
                .textFieldStyle(.plain)
                .focused($isTokenFocused)
        }
        .padding(8)
        .frame(width: 280)
        .background(Color(NSColor.controlBackgroundColor).opacity(0.5))
        .cornerRadius(6)
        .overlay(RoundedRectangle(cornerRadius: 6).stroke(Color.secondary.opacity(0.2), lineWidth: 1))
        .onTapGesture {
            self.presentTokenHistory()
        }
        .onChange(of: isTokenFocused) {
            if isTokenFocused {
                self.presentTokenHistory()
            } else if !showTokenHistory {
                self.wantsTokenHistory = false
            }
        }
        .onChange(of: token) {
            if wantsTokenHistory {
                self.refreshTokenHistoryPopover()
            }
        }
        .popover(isPresented: tokenHistoryPopoverBinding, arrowEdge: .bottom) {
            tokenHistoryPopover
        }
    }

    private var tokenHistoryPopover: some View {
        VStack(alignment: .leading, spacing: 0) {
            ForEach(visibleTokenHistory, id: \.token) { item in
                HStack(spacing: 4) {
                    Button(action: {
                        self.token = item.token
                        self.dismissTokenHistory()
                    }) {
                        HStack(spacing: 8) {
                            Image(systemName: item.token == normalizedToken ? "checkmark" : "key.fill")
                                .foregroundColor(.secondary)
                                .frame(width: 14)

                            Text(tokenHistoryTitle(item))
                                .font(.system(size: 12))
                                .lineLimit(1)
                                .truncationMode(.middle)

                            Spacer(minLength: 0)
                        }
                        .contentShape(Rectangle())
                        .padding(.leading, 10)
                        .padding(.vertical, 6)
                    }
                    .buttonStyle(.plain)

                    Button(action: {
                        self.deleteTokenHistoryItem(item)
                    }) {
                        Image(systemName: "trash")
                            .font(.system(size: 11, weight: .medium))
                            .foregroundColor(.secondary)
                            .frame(width: 24, height: 24)
                    }
                    .buttonStyle(.plain)
                }
                .padding(.trailing, 6)
            }
        }
        .frame(width: 280)
        .padding(.bottom, 6)
    }

    private func presentTokenHistory() {
        self.wantsTokenHistory = true
        self.refreshTokenHistoryPopover()
    }

    private func dismissTokenHistory() {
        self.wantsTokenHistory = false
        self.showTokenHistory = false
    }

    private func refreshTokenHistoryPopover() {
        self.tokenHistory = self.appContext.loadCacheTokenHistory()
        self.showTokenHistory = wantsTokenHistory && !visibleTokenHistory.isEmpty
    }

    private func deleteTokenHistoryItem(_ item: TokenHistoryItem) {
        do {
            try self.appContext.deleteCacheToken(item.token)
            self.tokenHistory = self.appContext.loadCacheTokenHistory()
            self.showTokenHistory = wantsTokenHistory && !visibleTokenHistory.isEmpty
        } catch {
            self.showAlert = true
            self.errorMessage = error.localizedDescription
        }
    }

    private func tokenHistoryTitle(_ item: TokenHistoryItem) -> String {
        guard let networkName = item.networkName, !networkName.isEmpty else {
            return item.token
        }

        return "\(item.token) (\(networkName))"
    }
    
    private func login() async {
        let finalToken = self.normalizedToken
        guard !finalToken.isEmpty else {
            return
        }

        self.isLoading = true
        self.dismissTokenHistory()
        defer {
            self.isLoading = false
        }
        
        do {
            _ = try await appContext.loginWith(token: finalToken)
            withAnimation(.spring(duration: 0.6, bounce: 0.2)) {
                self.appContext.appScene = .logined
            }
        } catch let err as SDLAPIError {
            self.showAlert = true
            self.errorMessage = err.message
        } catch let err {
            self.showAlert = true
            self.errorMessage = err.localizedDescription
        }
    }
    
}

// MARK: - 辅助 UI 组件
struct CustomTextField: View {
    let title: String
    @Binding var text: String
    let icon: String
    
    var body: some View {
        HStack {
            Image(systemName: icon)
                .foregroundColor(.secondary)
                .frame(width: 20)
            
            TextField(title, text: $text)
                .textFieldStyle(.plain)
        }
        .padding(8)
        .background(Color(NSColor.controlBackgroundColor).opacity(0.5))
        .cornerRadius(6)
        .overlay(RoundedRectangle(cornerRadius: 6).stroke(Color.secondary.opacity(0.2), lineWidth: 1))
    }
}

struct CustomSecureField: View {
    let title: String
    @Binding var text: String
    let icon: String
    
    var body: some View {
        HStack {
            Image(systemName: icon)
                .foregroundColor(.secondary)
                .frame(width: 20)
            SecureField(title, text: $text)
                .textFieldStyle(.plain)
        }
        .padding(8)
        .background(Color(NSColor.controlBackgroundColor).opacity(0.5))
        .cornerRadius(6)
        .overlay(RoundedRectangle(cornerRadius: 6).stroke(Color.secondary.opacity(0.2), lineWidth: 1))
    }
}

#Preview {
    LoginView()
        .environment(AppContext())
}
