import SwiftUI
import AuthenticationServices

@main
struct AIStudyAppApp: App {
    @AppStorage("hasCompletedOnboarding") private var hasCompletedOnboarding = false
    @AppStorage("appAppearance") private var appAppearance = "system"
    @StateObject private var authManager = AuthManager()

    private var effectiveColorScheme: ColorScheme? {
        switch appAppearance {
        case "dark": return .dark
        case "light": return .light
        default: return nil
        }
    }

    var body: some Scene {
        WindowGroup {
            Group {
                switch authManager.session {
                case .unknown:
                    SplashScreen()

                case .authenticated:
                    if hasCompletedOnboarding {
                        ContentView()
                            .environmentObject(authManager)
                    } else {
                        PostLoginOnboardingFlow(hasCompletedOnboarding: $hasCompletedOnboarding)
                            .environmentObject(authManager)
                    }

                case .disabled:
                    AccountStatusView(
                        icon: "person.crop.circle.badge.xmark",
                        title: "账号已被禁用",
                        message: "您的账号已被管理员禁用，如有疑问请联系客服。",
                        onBackToLogin: { authManager.session = .unauthenticated }
                    )

                case .deleted:
                    AccountStatusView(
                        icon: "person.crop.circle.badge.minus",
                        title: "账号已注销",
                        message: "您的账号已成功注销，欢迎随时回来重新注册。",
                        onBackToLogin: { authManager.session = .unauthenticated }
                    )

                case .expired, .unauthenticated:
                    PreLoginFlow()
                        .environmentObject(authManager)

                case .authenticating, .refreshing:
                    SplashScreen()
                }
            }
            .preferredColorScheme(effectiveColorScheme)
            .zxToast()
            .task {
                await authManager.restoreSession()
            }
        }
    }
}

// MARK: - Splash (session restore)

struct SplashScreen: View {
    var body: some View {
        ZStack {
            LinearGradient(colors: [Color(hex: "#0D0D20"), Color(hex: "#0F0F1A"), Color(hex: "#130D20")], startPoint: .top, endPoint: .bottom).ignoresSafeArea()
            Circle().fill(RadialGradient(colors: [Color(hex: "#7C6EFA", opacity: 0.25), .clear], center: .center, startRadius: 0, endRadius: 140)).frame(width: 280, height: 280).offset(y: -60).allowsHitTesting(false)
            VStack(spacing: 0) {
                RoundedRectangle(cornerRadius: 28).fill(LinearGradient(colors: [Color(hex: "#7C6EFA"), Color(hex: "#A78BFA"), Color(hex: "#F97316")], startPoint: .topLeading, endPoint: .bottomTrailing)).frame(width: 96, height: 96).overlay(Image(systemName: "brain.head.profile").font(.system(size: 44)).foregroundColor(.white.opacity(0.8))).shadow(color: Color(hex: "#7C6EFA", opacity: 0.5), radius: 40).padding(.bottom, 24)
                Text("知习").font(.system(size: 36, weight: .heavy)).tracking(-1).foregroundStyle(LinearGradient(colors: [Color(hex: "#A78BFA"), Color(hex: "#F0F0FF"), Color(hex: "#F97316")], startPoint: .leading, endPoint: .trailing))
                ProgressView().tint(Color(hex: "#F0F0FF", opacity: 0.5)).padding(.top, 32)
            }
        }
    }
}

// MARK: - Pre-login flow (Welcome → Login)

struct PreLoginFlow: View {
    @EnvironmentObject var authManager: AuthManager
    @State private var step = 0

    var body: some View {
        ZStack {
            switch step {
            case 0:
                WelcomePage(onContinue: { withAnimation(.easeInOut(duration: 0.5)) { step = 1 } })
            case 1:
                LoginPage()
            default:
                EmptyView()
            }
        }
    }
}

// MARK: - Post-login onboarding (Onboarding → GoalSetup)

struct PostLoginOnboardingFlow: View {
    @Binding var hasCompletedOnboarding: Bool
    @State private var step = 0

    var body: some View {
        ZStack {
            switch step {
            case 0:
                OnboardingPage { withAnimation { step = 1 } }
            case 1:
                GoalSetupPage { _ in hasCompletedOnboarding = true }
            default:
                EmptyView()
            }
        }
    }
}

// MARK: - Welcome

struct WelcomePage: View {
    let onContinue: () -> Void

    var body: some View {
        ZStack {
            ZXGradient.page.ignoresSafeArea()
            Circle().fill(RadialGradient(colors: [Color(hex: "#7C6EFA", opacity: 0.12), .clear], center: .topTrailing, startRadius: 0, endRadius: 260)).frame(width: 260, height: 260).offset(x: 80, y: -120).allowsHitTesting(false)
            VStack { Spacer()
            VStack(spacing: 14) {
                HStack(spacing: 6) { Image(systemName: "sparkles").font(.system(size: 12)); Text("AI 驱动").font(.system(size: 12, weight: .semibold)) }.foregroundColor(Color.zxAccent).padding(.horizontal, 12).padding(.vertical, 6).background(Color(hex: "#7C6EFA", opacity: 0.1)).clipShape(Capsule())
                Text("用 AI 重新定义\n你的学习方式").font(.system(size: 32, weight: .heavy)).tracking(-0.8).lineSpacing(4)
                VStack(spacing: 10) {
                    FeatureRow(icon: "brain.head.profile", title: "主动回忆", desc: "基于间隔重复的智能复习")
                    FeatureRow(icon: "mic.fill", title: "费曼解释", desc: "用自己的话讲出来")
                    FeatureRow(icon: "chart.bar.fill", title: "AI 分析", desc: "发现知识薄弱点")
                }
            }
            VStack(spacing: 12) {
                Button { onContinue() } label: {
                    Text("开始使用").font(.system(size: 16, weight: .bold)).foregroundColor(.white).frame(maxWidth: .infinity).frame(height: 56).background(ZXGradient.ctaButton).clipShape(RoundedRectangle(cornerRadius: 18)).shadow(color: Color(hex: "#7C6EFA", opacity: 0.4), radius: 20)
                }
            }.padding(.bottom, 32)
            }.padding(.horizontal, 20)
            }
        }
    }

struct FeatureRow: View {
    let icon: String; let title: String; let desc: String
    var body: some View {
        HStack(spacing: 14) {
            Image(systemName: icon).font(.system(size: 18)).foregroundColor(Color.zxPurple).frame(width: 40, height: 40).background(Color(hex: "#7C6EFA", opacity: 0.1)).clipShape(RoundedRectangle(cornerRadius: 12))
            VStack(alignment: .leading, spacing: 2) { Text(title).font(.system(size: 14, weight: .semibold)).foregroundColor(Color.zxF0); Text(desc).font(.system(size: 12)).foregroundColor(Color.zxF04) }
        }.padding(.horizontal, 16).padding(.vertical, 14).background(Color.zxFill003).overlay(RoundedRectangle(cornerRadius: 16).stroke(Color.zxBorder006, lineWidth: 1)).clipShape(RoundedRectangle(cornerRadius: 16))
    }
}

// MARK: - Login (with nonce support for iOS 15+)

struct LoginPage: View {
    @EnvironmentObject var authManager: AuthManager
    @State private var isLoggingIn = false
    @State private var errorMessage: String?
    @State private var loginTask: Task<Void, Never>?

    var body: some View {
        ZStack {
            ZXGradient.page.ignoresSafeArea()
            Circle().fill(RadialGradient(colors: [Color(hex: "#7C6EFA", opacity: 0.15), .clear], center: .top, startRadius: 0, endRadius: 300)).frame(width: 300, height: 300).offset(y: -80).allowsHitTesting(false)

            VStack { Spacer()
            VStack(spacing: 32) {
                RoundedRectangle(cornerRadius: 28).fill(LinearGradient(colors: [Color(hex: "#7C6EFA"), Color(hex: "#A78BFA"), Color(hex: "#F97316")], startPoint: .topLeading, endPoint: .bottomTrailing)).frame(width: 80, height: 80).overlay(Image(systemName: "brain.head.profile").font(.system(size: 36)).foregroundColor(.white.opacity(0.8))).shadow(color: Color(hex: "#7C6EFA", opacity: 0.3), radius: 30).padding(.bottom, -4)

                VStack(spacing: 8) {
                    Text("欢迎使用知习").font(.system(size: 26, weight: .heavy)).tracking(-0.6)
                    Text("使用 Apple 账号登录以同步学习数据").font(.system(size: 14)).foregroundColor(Color.zxF04)
                }

                if let error = errorMessage {
                    HStack(spacing: 6) {
                        Image(systemName: "exclamationmark.triangle.fill").font(.system(size: 12))
                        Text(error).font(.system(size: 13))
                    }
                    .foregroundColor(Color(hex: "#991B1B"))
                    .padding(.horizontal, 16).padding(.vertical, 10)
                    .background(Color(hex: "#FEE2E2"))
                    .clipShape(RoundedRectangle(cornerRadius: 10))
                }

                SignInWithAppleButton(.signIn) { request in
                    request.requestedScopes = [.fullName, .email]
                    request.nonce = LoginPage.generateNonceHash()
                } onCompletion: { result in
                    handleAppleResult(result)
                }
                .signInWithAppleButtonStyle(.white)
                .frame(height: 54)
                .clipShape(RoundedRectangle(cornerRadius: 16))
                .disabled(isLoggingIn)
                .overlay {
                    if isLoggingIn {
                        VStack(spacing: 8) {
                            ProgressView().tint(.white)
                            Button("取消") {
                                loginTask?.cancel()
                                isLoggingIn = false
                                errorMessage = nil
                            }
                            .font(.system(size: 11))
                            .foregroundColor(.white.opacity(0.7))
                        }
                        .frame(maxWidth: .infinity, maxHeight: .infinity)
                        .background(Color.black.opacity(0.6))
                        .clipShape(RoundedRectangle(cornerRadius: 16))
                    }
                }
            }.padding(.horizontal, 24).padding(.bottom, 48)
            } }
    }

    // MARK: - Nonce generation (iOS 15+ required)

    private static var currentRawNonce: String?

    /// SHA256 hash of the nonce, passed to Apple in the request
    private static func generateNonceHash() -> String {
        let raw = randomNonceString()
        currentRawNonce = raw
        return sha256(raw)
    }

    private static func randomNonceString(length: Int = 32) -> String {
        precondition(length > 0)
        let charset: [Character] = Array("0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._")
        var result = ""
        var remainingLength = length
        while remainingLength > 0 {
            var randoms = [UInt8](repeating: 0, count: 16)
            let errorCode = SecRandomCopyBytes(kSecRandomDefault, randoms.count, &randoms)
            if errorCode != errSecSuccess {
                fatalError("Unable to generate nonce. SecRandomCopyBytes failed with OSStatus \(errorCode)")
            }
            for random in randoms {
                if remainingLength == 0 { continue }
                if random < charset.count {
                    result.append(charset[Int(random)])
                    remainingLength -= 1
                }
            }
        }
        return result
    }

    private static func sha256(_ input: String) -> String {
        let inputData = Data(input.utf8)
        let hashedData = sha256Data(inputData)
        return hashedData.map { String(format: "%02x", $0) }.joined()
    }

    // MARK: - Apple result handler

    private func handleAppleResult(_ result: Result<ASAuthorization, Error>) {
        switch result {
        case .success(let auth):
            guard let credential = auth.credential as? ASAuthorizationAppleIDCredential,
                  let identityToken = credential.identityToken,
                  let tokenStr = String(data: identityToken, encoding: .utf8) else {
                withAnimation { errorMessage = "获取 Apple 身份信息失败" }
                return
            }
            let givenName = credential.fullName?.givenName
            let familyName = credential.fullName?.familyName
            let authCode = credential.authorizationCode.flatMap { String(data: $0, encoding: .utf8) }

            isLoggingIn = true
            errorMessage = nil

            loginTask = Task {
                do {
                    try Task.checkCancellation()
                    let rawNonce = LoginPage.currentRawNonce
                    LoginPage.currentRawNonce = nil // 用完即清，防重放
                    let resp = try await AuthService.shared.appleLogin(
                        identityToken: tokenStr,
                        authorizationCode: authCode,
                        givenName: givenName,
                        familyName: familyName,
                        nonce: rawNonce
                    )
                    try Task.checkCancellation()
                    await authManager.signIn(resp)
                    await MainActor.run { isLoggingIn = false }
                } catch is CancellationError {
                    await MainActor.run { isLoggingIn = false }
                } catch {
                    await MainActor.run {
                        isLoggingIn = false
                        errorMessage = "登录失败: \(error.localizedDescription)"
                    }
                }
            }

        case .failure(let error):
            if (error as NSError).code != ASAuthorizationError.canceled.rawValue {
                withAnimation { errorMessage = "Apple 登录失败: \(error.localizedDescription)" }
            }
        }
    }
}

import CryptoKit

// MARK: - SHA256 helper

private func sha256Data(_ data: Data) -> Data {
    let digest = SHA256.hash(data: data)
    return Data(digest)
}

// MARK: - Shared UI components

struct ZXTabBtn: View { let t: String; let active: Bool; let a: () -> Void; var body: some View { Button(action: a) { Text(t).font(.system(size: 13, weight: .semibold)).foregroundColor(active ? .white : Color.zxF05).frame(maxWidth: .infinity).frame(height: 36).background(active ? AnyView(ZXGradient.brand) : AnyView(Color.clear)).clipShape(RoundedRectangle(cornerRadius: 9)) } } }
struct ZXInputField: View { let placeholder: String; @Binding var text: String; var isSecure = false; var body: some View { HStack { if isSecure { SecureField(placeholder, text: $text) } else { TextField(placeholder, text: $text) } }.font(.system(size: 15)).tint(Color.zxPurple).padding(.horizontal, 16).frame(height: 52).background(Color.zxFill004).overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder008, lineWidth: 1)).clipShape(RoundedRectangle(cornerRadius: 14)) } }
struct SocialLoginBtn: View { let emoji: String; let text: String; let color: Color; let action: () -> Void; var body: some View { Button(action: action) { HStack(spacing: 10) { Text(emoji).font(.system(size: 18)); Text(text).font(.system(size: 11, weight: .medium)) }.foregroundColor(Color.zxF007).frame(maxWidth: .infinity).frame(height: 52).background(Color.zxFill004).overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder008, lineWidth: 1)).clipShape(RoundedRectangle(cornerRadius: 14)) } } }

// MARK: - Onboarding

struct OnboardingPage: View {
    let onContinue: () -> Void
    @State private var step = 0
    let titles = ["输入知识", "主动输出", "AI 分析", "掌握知识"]
    let descs = ["从任何地方收集并导入学习资料，构建你的专属知识库。", "通过间隔回忆和费曼解释法，将知识转化为长期记忆。", "AI 自动定位薄弱知识点，给出针对性的学习建议。", "系统性掌握每一个知识点，建立牢固的知识体系。"]

    var body: some View {
        ZStack {
            ZXGradient.page.ignoresSafeArea()
            VStack(spacing: 0) { Spacer()
            HStack(spacing: 6) { ForEach(0..<4, id: \.self) { i in RoundedRectangle(cornerRadius: 2).fill(i == step ? AnyShapeStyle(ZXGradient.brand) : AnyShapeStyle(Color(hex: "#FFFFFF", opacity: 0.1))).frame(width: i == step ? 24 : 8, height: 4) } }
            VStack(spacing: 12) { Text(titles[step]).font(.system(size: 24, weight: .heavy)).tracking(-0.5); Text(descs[step]).font(.system(size: 14)).foregroundColor(Color.zxF04).lineSpacing(4).multilineTextAlignment(.center) }.padding(.top, 32).padding(.bottom, 40)
            Button { if step < 3 { withAnimation { step += 1 } } else { onContinue() } } label: { Text(step < 3 ? "下一步" : "开始使用").font(.system(size: 16, weight: .bold)).foregroundColor(.white).frame(maxWidth: .infinity).frame(height: 56).background(ZXGradient.ctaButton).clipShape(RoundedRectangle(cornerRadius: 18)).shadow(color: Color(hex: "#7C6EFA", opacity: 0.4), radius: 20) }
            Button("跳过") { onContinue() }.font(.system(size: 12)).foregroundColor(Color.zxF03).padding(.top, 12).padding(.bottom, 32)
            }.padding(.horizontal, 20)
        }
    }
}

// MARK: - Account Status (disabled / deleted)

struct AccountStatusView: View {
    let icon: String
    let title: String
    let message: String
    let onBackToLogin: () -> Void

    var body: some View {
        ZStack {
            ZXGradient.page.ignoresSafeArea()
            VStack(spacing: 24) {
                Image(systemName: icon)
                    .font(.system(size: 56))
                    .foregroundColor(Color.zxCoral.opacity(0.6))
                    .padding(.bottom, 8)

                Text(title)
                    .font(.system(size: 22, weight: .heavy))
                    .foregroundColor(Color.zxF0)

                Text(message)
                    .font(.system(size: 15))
                    .foregroundColor(Color.zxF04)
                    .multilineTextAlignment(.center)
                    .lineSpacing(4)
                    .padding(.horizontal, 40)

                Button {
                    onBackToLogin()
                } label: {
                    Text("返回首页")
                        .font(.system(size: 15, weight: .semibold))
                        .foregroundColor(Color.zxOnPrimary)
                        .frame(width: 200, height: 48)
                        .background(ZXGradient.brand)
                        .clipShape(RoundedRectangle(cornerRadius: 14))
                }
                .padding(.top, 12)
            }
        }
    }
}

// MARK: - GoalSetup

struct GoalSetupPage: View {
    let onComplete: (Bool) -> Void
    @State private var selectedGoal = ""
    let goals = [("🧑‍🎓","备考考试","公考、考研、考证等"),("💼","职业技能","编程、设计、产品等"),("📚","通识学习","扩充知识面"),("🎯","自定义","设定自己的目标")]
    @State private var selectedMethod = ""
    let methods = ["间隔回忆","费曼技巧","AI 分析"]
    @State private var dailyMins = "30 分钟"
    let times = ["15 分钟","30 分钟","1 小时","不限制"]

    var body: some View {
        ZStack { ZXGradient.page.ignoresSafeArea()
        VStack(spacing: 0) { Spacer()
        Text("设定你的学习目标").font(.system(size: 24, weight: .heavy)).tracking(-0.5).foregroundColor(Color.zxF0).padding(.bottom, 24)
        ScrollView { VStack(spacing: 16) {
            VStack(alignment: .leading, spacing: 10) { Text("学习目标").font(.system(size: 12, weight: .semibold)).foregroundColor(Color.zxF035).tracking(0.5)
                ForEach(goals, id: \.1) { g in let sel = selectedGoal == g.1; Button { selectedGoal = g.1 } label: { HStack(spacing: 12) { Text(g.0).font(.system(size: 22)).frame(width: 44, height: 44).background(sel ? Color(hex: "#7C6EFA", opacity: 0.15) : Color.zxFill005).clipShape(RoundedRectangle(cornerRadius: 12)); VStack(alignment: .leading, spacing: 2) { Text(g.1).font(.system(size: 15, weight: .semibold)).foregroundColor(sel ? Color.zxPurple : Color.zxF0); Text(g.2).font(.system(size: 12)).foregroundColor(Color.zxF04) }; Spacer(); Circle().stroke(sel ? Color.zxPurple : Color(hex: "#FFFFFF", opacity: 0.2), lineWidth: 2).frame(width: 22, height: 22).overlay { if sel { Circle().fill(Color.zxPurple).frame(width: 12, height: 12) } } }.padding(14).background(sel ? Color(hex: "#7C6EFA", opacity: 0.08) : Color.zxFill003).overlay(RoundedRectangle(cornerRadius: 16).stroke(sel ? Color(hex: "#7C6EFA", opacity: 0.25) : Color.zxBorder006, lineWidth: 1)).clipShape(RoundedRectangle(cornerRadius: 16)) }.foregroundColor(.primary) } }
            VStack(alignment: .leading, spacing: 10) { Text("学习方法").font(.system(size: 12, weight: .semibold)).foregroundColor(Color.zxF035).tracking(0.5)
                HStack(spacing: 8) { ForEach(methods, id: \.self) { m in let sel = selectedMethod == m; Button { selectedMethod = m } label: { Text(m).font(.system(size: 13)).fontWeight(sel ? .semibold : .regular).foregroundColor(sel ? Color.zxPurple : Color.zxF05).padding(.horizontal, 16).padding(.vertical, 10).background(sel ? Color(hex: "#7C6EFA", opacity: 0.1) : Color.zxFill003).overlay(RoundedRectangle(cornerRadius: 20).stroke(sel ? Color(hex: "#7C6EFA", opacity: 0.25) : Color.zxBorder006, lineWidth: 1)).clipShape(RoundedRectangle(cornerRadius: 20)) }.foregroundColor(.primary) } } }
            VStack(alignment: .leading, spacing: 10) { Text("每日学习时间").font(.system(size: 12, weight: .semibold)).foregroundColor(Color.zxF035).tracking(0.5)
                HStack(spacing: 8) { ForEach(times, id: \.self) { t in let sel = dailyMins == t; Button { dailyMins = t } label: { Text(t).font(.system(size: 12)).fontWeight(sel ? .semibold : .regular).foregroundColor(sel ? Color.zxPurple : Color.zxF05).frame(maxWidth: .infinity).frame(height: 40).background(sel ? Color(hex: "#7C6EFA", opacity: 0.1) : Color.zxFill003).overlay(RoundedRectangle(cornerRadius: 12).stroke(sel ? Color(hex: "#7C6EFA", opacity: 0.25) : Color.zxBorder006, lineWidth: 1)).clipShape(RoundedRectangle(cornerRadius: 12)) }.foregroundColor(.primary) } } } }
        Button { onComplete(true) } label: { Text("开始学习").font(.system(size: 16, weight: .bold)).foregroundColor(.white).frame(maxWidth: .infinity).frame(height: 56).background(ZXGradient.ctaButton).clipShape(RoundedRectangle(cornerRadius: 18)).shadow(color: Color(hex: "#7C6EFA", opacity: 0.4), radius: 20) }.padding(.top, 24).padding(.bottom, 32).padding(.horizontal, 20)
        } } }
    }
}
