import SwiftUI

struct AppLockSetupView: View {
    @Environment(\.nahbarTheme) var theme
    @Environment(\.dismiss) var dismiss
    @EnvironmentObject var lockManager: AppLockManager

    /// true = user wants to disable or change PIN (must verify old PIN first if changing)
    let isDisabling: Bool

    @State private var step: Step = .first
    @State private var firstPIN = ""
    @State private var entered = ""
    @State private var errorMessage = ""
    @State private var showError = false
    @State private var errorOffset: CGFloat = 0

    private let pinLength = 6

    enum Step { case first, confirm }

    var body: some View {
        ZStack {
            theme.backgroundPrimary.ignoresSafeArea()

            VStack(spacing: 0) {
                // Close
                HStack {
                    Button { dismiss() } label: {
                        Image(systemName: "xmark")
                            .font(.system(size: 15, weight: .light))
                            .foregroundStyle(theme.contentTertiary)
                            .frame(width: 36, height: 36)
                            .background(theme.surfaceCard)
                            .clipShape(Circle())
                    }
                    Spacer()
                }
                .padding(.horizontal, 20)
                .padding(.top, 20)

                Spacer()

                VStack(spacing: 8) {
                    Text(title)
                        .font(.system(size: 22, weight: .light, design: theme.displayDesign))
                        .foregroundStyle(theme.contentPrimary)
                    Text(subtitle)
                        .font(.system(size: 15))
                        .foregroundStyle(theme.contentSecondary)
                        .multilineTextAlignment(.center)
                        .padding(.horizontal, 40)
                }

                Spacer().frame(height: 44)

                // PIN dots
                HStack(spacing: 20) {
                    ForEach(0..<pinLength, id: \.self) { i in
                        Circle()
                            .fill(i < entered.count ? theme.accent : Color.clear)
                            .frame(width: 14, height: 14)
                            .overlay(
                                Circle().stroke(
                                    i < entered.count ? theme.accent : theme.contentTertiary,
                                    lineWidth: 1.5
                                )
                            )
                    }
                }
                .offset(x: errorOffset)

                Spacer().frame(height: 14)

                Text(showError ? errorMessage : " ")
                    .font(.system(size: 13))
                    .foregroundStyle(.red.opacity(0.8))
                    .animation(.easeInOut(duration: 0.2), value: showError)

                Spacer()

                PINPadView { key in handleKey(key) }
                    .padding(.horizontal, 44)

                Spacer().frame(height: 60)
            }
        }
    }

    // MARK: - Labels

    private var title: String {
        if isDisabling { return String(localized: "Code eingeben") }
        return step == .first ? String(localized: "Code festlegen") : String(localized: "Code bestätigen")
    }

    private var subtitle: String {
        if isDisabling { return String(localized: "Gib deinen Code ein, um den Schutz zu deaktivieren") }
        return step == .first
            ? String(localized: "Wähle einen 6-stelligen Code")
            : String(localized: "Gib den Code zur Bestätigung nochmal ein")
    }

    // MARK: - Input

    private func handleKey(_ key: PINKey) {
        switch key {
        case .digit(let d):
            guard entered.count < pinLength else { return }
            entered.append(d)
            if entered.count == pinLength { advance() }
        case .delete:
            if !entered.isEmpty { entered.removeLast() }
        }
    }

    private func advance() {
        if isDisabling {
            if lockManager.verifyPIN(entered) {
                lockManager.deletePIN()
                lockManager.isEnabled = false
                dismiss()
            } else {
                shake(String(localized: "Falscher Code"))
            }
            return
        }

        switch step {
        case .first:
            firstPIN = entered
            entered = ""
            withAnimation(.easeInOut(duration: 0.2)) { step = .confirm }
        case .confirm:
            if entered == firstPIN {
                lockManager.setPIN(entered)
                lockManager.isEnabled = true
                dismiss()
            } else {
                shake(String(localized: "Codes stimmen nicht überein"))
                // Reset to step 1
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.6) {
                    withAnimation(.easeInOut(duration: 0.2)) { step = .first }
                    firstPIN = ""
                }
            }
        }
    }

    // MARK: - Shake feedback

    private func shake(_ message: String) {
        errorMessage = message
        showError = true
        entered = ""
        let pattern: [(CGFloat, Double)] = [(10,0), (-10,0.07), (6,0.14), (-4,0.21), (0,0.28)]
        for (offset, delay) in pattern {
            DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
                withAnimation(.easeInOut(duration: 0.07)) { errorOffset = offset }
            }
        }
        DispatchQueue.main.asyncAfter(deadline: .now() + 2.5) {
            withAnimation { showError = false }
        }
    }
}
