//
//  ResetPasswordView.swift
//  punchnet
//
//  Created by 安礼成 on 2026/3/9.
//
import SwiftUI
import Observation

// MARK: - 注册根视图
struct RegisterRootView: View {
    @State private var registerModel = RegisterModel()
    @Environment(AppContext.self) private var appContext: AppContext
    
    var body: some View {
        ZStack(alignment: .center) {
            Color.clear
            
            ZStack(alignment: .center) {
                switch registerModel.stage {
                case .requestVerifyCode:
                    RegisterRequestVerifyCodeView()
                case .submitVerifyCode:
                    RegisterSubmitVerifyCodeView()
                case .setPassword:
                    RegisterSetPasswordView()
                case .success:
                    RegisterSuccessView()
                }
            }
            .transition(.asymmetric(
                insertion: .move(edge: registerModel.transitionEdge).combined(with: .opacity),
                removal: .move(edge: registerModel.transitionEdge == .trailing ? .leading : .trailing).combined(with: .opacity)
            ))
        }
        .environment(registerModel)
        // --- 核心改动：使用 overlay ---
        .overlay(alignment: .topLeading) {
            // 仅在非成功页面显示返回按钮
            switch registerModel.stage {
            case .success:
                EmptyView()
            default:
                Button(action: {
                    // 执行返回逻辑，例如重置到登录
                    withAnimation(.spring(duration: 0.6, bounce: 0.2)) {
                        self.appContext.appScene = .login(username: nil)
                    }
                }) {
                    HStack {
                        Image(systemName: "chevron.left")
                            .font(.system(size: 16, weight: .semibold))
                            .padding(5)
                        
                        Text("首页")
                            .font(.system(size: 16, weight: .regular))
                    }
                    .contentShape(Rectangle()) // 扩大点击热区
                }
                .buttonStyle(.plain)
                .padding([.top, .leading], 16) // 控制距离窗口边缘的边距
                .transition(.opacity) // 按钮出现的动画
            }
        }
    }
}

// MARK: - 封装的输入框组件
struct PunchTextField: View {
    let icon: String
    let placeholder: String
    @Binding var text: String
    var isSecure: Bool = false
    var isDisabled: Bool = false

    var body: some View {
        HStack(spacing: 12) {
            Image(systemName: icon)
                .foregroundColor(.secondary)
                .frame(width: 20)
            
            if isSecure {
                SecureField(placeholder, text: $text)
                    .textFieldStyle(.plain)
            } else {
                TextField(placeholder, text: $text)
                    .textFieldStyle(.plain)
                    .disabled(isDisabled)
            }
        }
        .padding(10)
        .background(Color.primary.opacity(isDisabled ? 0.02 : 0.05))
        .cornerRadius(8)
        .overlay(
            RoundedRectangle(cornerRadius: 8)
                .stroke(Color.primary.opacity(0.1), lineWidth: 1)
        )
    }
}

// MARK: - 第一步：获取验证码
struct RegisterRequestVerifyCodeView: View {
    @Environment(RegisterModel.self) var registerModel: RegisterModel
    @State private var isProcessing = false
    
    // 错误提示
    @State private var showAlert: Bool = false
    @State private var errorMessage: String = ""

    var body: some View {
        @Bindable var model = registerModel
        
        VStack(spacing: 24) {
            headerSection(title: "创建个人网络", subtitle: "输入手机号开始注册")

            VStack(spacing: 16) {
                PunchTextField(icon: "phone.fill", placeholder: "手机号", text: $model.phoneNumber)
            }
            .frame(width: 280)

            Button(action: {
                Task { @MainActor in
                    await self.requestVerifyCode(phoneNumber: model.phoneNumber)
                }
            }) {
                Text("获取验证码")
                    .fontWeight(.medium)
                    .frame(maxWidth: .infinity)
            }
            .buttonStyle(.borderedProminent)
            .controlSize(.large)
            .frame(width: 280)
            .disabled(SDLUtil.identifyContact(model.phoneNumber) != .phone || isProcessing)
        }
        .padding(40)
        .alert(isPresented: $showAlert) {
            Alert(title: Text("提示"), message: Text(self.errorMessage))
        }
    }

    private func requestVerifyCode(phoneNumber: String) async {
        self.isProcessing = true
        defer {
            self.isProcessing = false
        }
        
        if phoneNumber.isEmpty {
            self.showAlert = true
            self.errorMessage = "手机号为空"
            return
        }
        
        switch SDLUtil.identifyContact(phoneNumber) {
        case .phone:
            do {
                let registerSession = try await self.registerModel.requestVerifyCode(phoneNumber: phoneNumber)
                withAnimation(.spring(duration: 0.6, bounce: 0.2)) {
                    self.registerModel.stage = .submitVerifyCode
                    self.registerModel.phoneNumber = phoneNumber
                    self.registerModel.sessionId = registerSession.sessionId
                    
                    self.registerModel.transitionEdge = .trailing
                }
            } catch let err as SDLAPIError {
                self.showAlert = true
                self.errorMessage = err.message
            } catch let err {
                self.showAlert = true
                self.errorMessage = err.localizedDescription
            }
        default:
            self.showAlert = true
            self.errorMessage = "手机号格式错误"
        }
    }
    
}

// MARK: - 第二步：验证
struct RegisterSubmitVerifyCodeView: View {
    @Environment(RegisterModel.self) var registerModel: RegisterModel
    
    @State private var code: String = ""
    @State private var isProcessing = false
    
    // 错误提示
    @State private var showAlert: Bool = false
    @State private var errorMessage: String = ""
    
    // 重新发送是否可以使用
    @State private var isEnabled: Bool = false
    @State private var remainingSeconds = 60
    @State private var timer: Timer? = nil
    
    // 判断验证码是否正确
    var validInputCode: Bool {
        return !self.code.isEmpty && self.code.count == 6 && self.code.allSatisfy {$0.isNumber}
    }

    var body: some View {
        VStack(spacing: 24) {
            headerSection(title: "身份验证", subtitle: "验证码已发送至 \(registerModel.phoneNumber)")

            VStack(alignment: .trailing, spacing: 16) {
                PunchTextField(icon: "envelope.badge", placeholder: "输入 6 位验证码", text: $code)
                
                Button {
                    Task { @MainActor in
                        await self.resendVerifyCodeAction(phoneNumber: registerModel.phoneNumber)
                    }
                } label: {
                    if isEnabled {
                        Text("没有收到？重新获取")
                    } else {
                        Text("重新获取 (\(remainingSeconds)s)")
                    }
                }
                .buttonStyle(.link)
                .font(.caption)
                .disabled(!isEnabled) // 倒计时期间禁用按钮
            }
            .frame(width: 280)

            VStack(spacing: 12) {
                Button(action: {
                    Task { @MainActor in
                        await self.submitVerifyCode(sessionId: registerModel.sessionId)
                    }
                }) {
                    Text("验证并设置密码")
                        .fontWeight(.medium)
                        .frame(maxWidth: .infinity)
                }
                .buttonStyle(.borderedProminent)
                .controlSize(.large)
                .disabled(!self.validInputCode)
                
                Button("返回上一步") {
                    withAnimation(.spring(duration: 0.6, bounce: 0.2)) {
                        self.registerModel.stage = .requestVerifyCode
                        
                        self.registerModel.transitionEdge = .leading
                    }
                }
                .buttonStyle(.plain)
                .foregroundColor(.secondary)
            }
            .frame(width: 280)
        }
        .padding(40)
        .alert(isPresented: $showAlert) {
            Alert(title: Text("提示"), message: Text(errorMessage))
        }
        .task {
            await self.startCountdown()
        }
    }
    
    // 重新发送验证码
    private func resendVerifyCodeAction(phoneNumber: String) async {
        do {
            let result = try await self.registerModel.requestVerifyCode(phoneNumber: phoneNumber)
            print("send verify code result: \(result)")
        } catch let err {
            print("resend verify get error: \(err)")
        }
        // 重新计时
        await self.startCountdown()
    }
    
    // 重新倒计时
    private func startCountdown() async {
        self.isEnabled = false
        self.remainingSeconds = 60
        for sec in (1...self.remainingSeconds).reversed() {
            self.remainingSeconds = sec
            try? await Task.sleep(nanoseconds: 1_000_000_000)
        }
        self.isEnabled = true
    }

    // 提交验证码
    private func submitVerifyCode(sessionId: Int) async {
        self.isProcessing = true
        defer {
            self.isProcessing = false
        }
        do {
            _ = try await self.registerModel.submitVerifyCode(sessionId: sessionId, verifyCode: self.code)
            withAnimation(.spring(duration: 0.6, bounce: 0.2)) {
                self.registerModel.stage = .setPassword
                self.registerModel.transitionEdge = .trailing
            }
        } catch let err as SDLAPIError {
            self.showAlert = true
            self.errorMessage = err.message
        } catch let err {
            self.showAlert = true
            self.errorMessage = err.localizedDescription
        }
    }
}

// MARK: - 第三步：设置密码
struct RegisterSetPasswordView: View {
    @Environment(RegisterModel.self) var registerModel: RegisterModel
    
    @State private var password = ""
    @State private var confirm = ""
    @State private var isProcessing = false
    
    // 错误提示
    @State private var showAlert: Bool = false
    @State private var errorMessage: String = ""

    // 提示错误信息
    var passwordError: String? {
        if password.isEmpty || confirm.isEmpty {
            return nil
        }
        
        if password != confirm {
            return "两次输入的密码不一致"
        }
        if password.count < 8 {
            return "密码至少需要 8 位"
        }
        return nil
    }

    var body: some View {
        VStack(spacing: 24) {
            headerSection(title: "设置安全密码", subtitle: "最后一步，请确保密码足够强大")

            VStack(spacing: 12) {
                PunchTextField(icon: "lock.shield", placeholder: "新密码", text: $password, isSecure: true)
                PunchTextField(icon: "lock.shield", placeholder: "确认密码", text: $confirm, isSecure: true)
                if let error = passwordError {
                    Text(error)
                        .font(.caption)
                        .foregroundColor(.red)
                        .frame(width: 280, alignment: .leading)
                }
            }
            .frame(width: 280)

            Button(action: {
                Task { @MainActor in
                    await self.handleRegister(sessionId: registerModel.sessionId)
                }
            }) {
                if isProcessing {
                    ProgressView()
                        .controlSize(.small)
                } else {
                    Text("完成注册")
                        .fontWeight(.medium)
                        .frame(maxWidth: .infinity)
                }
            }
            .buttonStyle(.borderedProminent)
            .controlSize(.large)
            .frame(width: 280)
            .disabled(passwordError != nil)
        }
        .padding(40)
        .alert(isPresented: $showAlert) {
            Alert(title: Text("提示"), message: Text(self.errorMessage))
        }
    }

    private func handleRegister(sessionId: Int) async {
        self.isProcessing = true
        defer {
            self.isProcessing = false
        }
        do {
            _ = try await self.registerModel.register(sessionId: sessionId, password: self.password)
            withAnimation(.spring(duration: 0.6, bounce: 0.2)) {
                self.registerModel.stage = .success
                self.registerModel.transitionEdge = .trailing
            }
        } catch let err as SDLAPIError {
            self.showAlert = true
            self.errorMessage = err.message
        } catch {
            self.showAlert = true
            self.errorMessage = "注册失败，重稍后重试"
        }
    }
    
}

// MARK: 第四步 注册成功
struct RegisterSuccessView: View {
    @Environment(AppContext.self) private var appContext: AppContext
    @Environment(RegisterModel.self) private var registerModel: RegisterModel

    // MARK: - 动画状态
    @State private var animateIcon: Bool = false // 用于呼吸灯效果
    @State private var animateText: Bool = false // 用于文本延迟浮现

    var body: some View {
        VStack(spacing: 32) {
            Spacer()
            
            // MARK: - 成功动画图标 (带呼吸灯效果)
            ZStack {
                // 外层呼吸圈
                Circle()
                    .fill(Color.green.opacity(0.1))
                    .frame(width: 100, height: 100)
                    // 呼吸逻辑：缩放和透明度变化
                    .scaleEffect(animateIcon ? 1.1 : 0.95)
                    .opacity(animateIcon ? 0.8 : 1.0)
                
                // 内层 Checkmark
                Image(systemName: "checkmark.seal.fill")
                    .font(.system(size: 56))
                    .foregroundStyle(.green.gradient)
                    // Checkmark 本身做轻微缩放
                    .scaleEffect(animateIcon ? 1.05 : 1.0)
            }
            // 整个图标组的弹出动画
            .transition(.move(edge: .bottom).combined(with: .opacity))
            
            // MARK: - 文本和按钮
            VStack(spacing: 32) {
                VStack(spacing: 12) {
                    Text("注册成功")
                        .font(.title.bold())
                    
                    Text("您的 PunchNet 账号已就绪。\n现在可以登录并开始构建您的私有网络了。")
                        .font(.subheadline)
                        .foregroundColor(.secondary)
                        .multilineTextAlignment(.center)
                }
                
                Button(action: {
                    // 关闭当前注册窗口
                    withAnimation(.spring(duration: 0.6, bounce: 0.2)) {
                        self.appContext.appScene = .login(username: registerModel.phoneNumber)
                    }
                }) {
                    Text("立即开始使用")
                        .fontWeight(.bold)
                        .frame(width: 200)
                }
                .buttonStyle(.borderedProminent)
                .controlSize(.large)
                .tint(.green)
            }
            // 文本和按钮比图标晚一点出现，形成层次感
            .opacity(animateText ? 1.0 : 0.0)
            .offset(y: animateText ? 0 : 20)
        }
        .padding(40)
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color(NSColor.windowBackgroundColor)) // 确保背景干净
        .onAppear {
            self.startAnimations()
        }
    }

    // MARK: - 动画逻辑
    private func startAnimations() {
        // 1. 图标呼吸灯：无限循环，缓入缓出
        withAnimation(.easeInOut(duration: 1.5).repeatForever(autoreverses: true)) {
            animateIcon = true
        }
        
        // 2. 文本延迟弹出：延迟 0.4 秒，使用弹簧效果
        withAnimation(.spring(duration: 0.6, bounce: 0.3).delay(0.4)) {
            animateText = true
        }
    }
}

// MARK: - 辅助视图
extension View {
    
    func headerSection(title: String, subtitle: String) -> some View {
        VStack(spacing: 8) {
            Image(systemName: "shield.lefthalf.filled")
                .font(.system(size: 42))
                .foregroundStyle(.blue.gradient)
            
            Text(title)
                .font(.title2.bold())
            
            Text(subtitle)
                .font(.subheadline)
                .foregroundColor(.secondary)
                .multilineTextAlignment(.center)
        }
    }
    
}
