import SwiftUI

struct LoginScreen: View {
    @EnvironmentObject var appState: AppState

    // Login mode
    @State private var usePasswordLogin = false

    // OTP flow
    @State private var step: OtpStep = .phone
    @State private var phoneNumber = ""
    @State private var otpCode = ""
    @State private var otpUuid = ""

    // Password flow
    @State private var username = ""
    @State private var password = ""
    @State private var showPassword = false

    // Shared state
    @State private var isLoading = false
    @State private var error: String?

    private enum OtpStep {
        case phone
        case otp
    }

    var body: some View {
        GeometryReader { geo in
            ScrollView {
                VStack(spacing: 16) {
                    Spacer().frame(height: 40)

                    Image("PayfritLogoLight")
                        .resizable()
                        .scaledToFit()
                        .frame(width: 180)

                    Text("Payfrit Works")
                        .font(.system(size: 28, weight: .bold))

                    Text("Sign in to view and claim tasks")
                        .foregroundColor(.secondary)
                        .font(.subheadline)

                    if IS_DEV {
                        Text("DEV MODE — OTP: 123456")
                            .font(.caption)
                            .foregroundColor(.red)
                            .fontWeight(.medium)
                    }

                    Spacer().frame(height: 8)

                    // Error message
                    if let error = error {
                        HStack {
                            Image(systemName: "exclamationmark.circle.fill")
                                .foregroundColor(.red)
                            Text(error)
                                .foregroundColor(.red)
                                .font(.callout)
                            Spacer()
                        }
                        .padding(12)
                        .background(Color.red.opacity(0.1))
                        .cornerRadius(8)
                    }

                    // Main form
                    if usePasswordLogin {
                        passwordLoginView
                    } else {
                        switch step {
                        case .phone: phoneEntryView
                        case .otp: otpEntryView
                        }
                    }

                    Spacer().frame(height: 16)

                    // Toggle login mode
                    Button {
                        withAnimation {
                            usePasswordLogin.toggle()
                            error = nil
                            // Reset states
                            step = .phone
                            otpCode = ""
                            password = ""
                        }
                    } label: {
                        Text(usePasswordLogin ? "Use phone number instead" : "Use email & password instead")
                            .font(.subheadline)
                            .foregroundColor(.payfritGreen)
                    }

                    Spacer()
                }
                .padding(.horizontal, 24)
                .frame(minHeight: geo.size.height)
            }
            .scrollDismissesKeyboard(.interactively)
        }
        .background(Color(.systemGroupedBackground))
    }

    // MARK: - Phone Entry View

    private var phoneEntryView: some View {
        VStack(spacing: 16) {
            Text("Phone Number")
                .font(.system(size: 13, weight: .medium))
                .foregroundColor(.secondary)
                .frame(maxWidth: .infinity, alignment: .leading)

            HStack(spacing: 0) {
                Text("+1")
                    .font(.system(size: 17, weight: .medium))
                    .padding(.leading, 16)

                Divider()
                    .frame(height: 20)
                    .padding(.horizontal, 12)

                TextField("(555) 555-1234", text: $phoneNumber)
                    .font(.system(size: 17))
                    .keyboardType(.phonePad)
                    .textContentType(.telephoneNumber)
                    .padding(.trailing, 16)
            }
            .frame(height: 52)
            .background(Color(.systemBackground))
            .cornerRadius(10)
            .overlay(
                RoundedRectangle(cornerRadius: 10)
                    .stroke(Color(.systemGray4), lineWidth: 1)
            )

            let canSend = phoneNumber.filter { $0.isNumber }.count >= 10 && !isLoading

            Button(action: sendOtp) {
                if isLoading {
                    ProgressView()
                        .progressViewStyle(CircularProgressViewStyle(tint: .white))
                        .frame(maxWidth: .infinity, minHeight: 50)
                } else {
                    Text("Send Login Code")
                        .font(.headline)
                        .frame(maxWidth: .infinity, minHeight: 50)
                }
            }
            .buttonStyle(.borderedProminent)
            .tint(canSend ? .payfritGreen : .payfritGreen.opacity(0.5))
            .disabled(!canSend)
        }
    }

    // MARK: - OTP Entry View

    private var otpEntryView: some View {
        VStack(spacing: 16) {
            VStack(spacing: 4) {
                Text("We sent a code to")
                    .font(.subheadline)
                    .foregroundColor(.secondary)
                Text(formattedPhone)
                    .font(.headline)
            }

            TextField("000000", text: $otpCode)
                .font(.system(size: 28, weight: .semibold, design: .monospaced))
                .multilineTextAlignment(.center)
                .keyboardType(.numberPad)
                .textContentType(.oneTimeCode)
                .tracking(8)
                .frame(height: 56)
                .background(Color(.systemBackground))
                .cornerRadius(10)
                .overlay(
                    RoundedRectangle(cornerRadius: 10)
                        .stroke(Color(.systemGray4), lineWidth: 1)
                )
                .onChange(of: otpCode) { newValue in
                    otpCode = String(newValue.prefix(6))
                }

            let canVerify = otpCode.count == 6 && !isLoading

            Button(action: verifyOtp) {
                if isLoading {
                    ProgressView()
                        .progressViewStyle(CircularProgressViewStyle(tint: .white))
                        .frame(maxWidth: .infinity, minHeight: 50)
                } else {
                    Text("Sign In")
                        .font(.headline)
                        .frame(maxWidth: .infinity, minHeight: 50)
                }
            }
            .buttonStyle(.borderedProminent)
            .tint(canVerify ? .payfritGreen : .payfritGreen.opacity(0.5))
            .disabled(!canVerify)

            HStack(spacing: 24) {
                Button("Resend Code") {
                    sendOtp()
                }
                .foregroundColor(.payfritGreen)

                Button("Change Number") {
                    step = .phone
                    otpCode = ""
                    error = nil
                }
                .foregroundColor(.secondary)
            }
            .font(.subheadline)
        }
    }

    // MARK: - Password Login View

    private var passwordLoginView: some View {
        VStack(spacing: 12) {
            TextField("Email or Phone", text: $username)
                .textFieldStyle(.roundedBorder)
                .textContentType(.emailAddress)
                .autocapitalization(.none)
                .disableAutocorrection(true)

            ZStack(alignment: .trailing) {
                Group {
                    if showPassword {
                        TextField("Password", text: $password)
                            .textContentType(.password)
                    } else {
                        SecureField("Password", text: $password)
                            .textContentType(.password)
                    }
                }
                .textFieldStyle(.roundedBorder)
                .onSubmit { loginWithPassword() }

                Button {
                    showPassword.toggle()
                } label: {
                    Image(systemName: showPassword ? "eye.slash.fill" : "eye.fill")
                        .foregroundColor(.secondary)
                        .font(.subheadline)
                }
                .padding(.trailing, 8)
            }

            Button(action: loginWithPassword) {
                if isLoading {
                    ProgressView()
                        .progressViewStyle(CircularProgressViewStyle(tint: .white))
                        .frame(maxWidth: .infinity, minHeight: 44)
                } else {
                    Text("Sign In")
                        .font(.headline)
                        .frame(maxWidth: .infinity, minHeight: 44)
                }
            }
            .buttonStyle(.borderedProminent)
            .tint(.payfritGreen)
            .disabled(isLoading)
        }
    }

    // MARK: - Helpers

    private var formattedPhone: String {
        let digits = phoneNumber.filter { $0.isNumber }
        guard digits.count >= 10 else { return "+1 \(phoneNumber)" }
        let area = String(digits.prefix(3))
        let mid = String(digits.dropFirst(3).prefix(3))
        let last = String(digits.dropFirst(6).prefix(4))
        return "+1 (\(area)) \(mid)-\(last)"
    }

    // MARK: - API Calls

    private func sendOtp() {
        let cleanPhone = phoneNumber.filter { $0.isNumber }
        guard cleanPhone.count >= 10 else {
            error = "Please enter a valid phone number"
            return
        }

        isLoading = true
        error = nil

        Task {
            do {
                let response = try await APIService.shared.sendLoginOtp(phone: "+1\(cleanPhone)")
                otpUuid = response.uuid
                step = .otp
            } catch {
                self.error = "Failed to send code. Please try again."
            }
            isLoading = false
        }
    }

    private func verifyOtp() {
        isLoading = true
        error = nil

        Task {
            do {
                let response = try await APIService.shared.verifyLoginOtp(uuid: otpUuid, otp: otpCode)
                let resolvedPhoto = APIService.resolvePhotoUrl(response.photoUrl)
                await AuthStorage.shared.saveAuth(
                    userId: response.userId,
                    token: response.token,
                    userName: response.userFirstName,
                    photoUrl: resolvedPhoto
                )
                appState.setAuth(
                    userId: response.userId,
                    token: response.token,
                    userName: response.userFirstName,
                    photoUrl: resolvedPhoto
                )
            } catch {
                self.error = "Invalid code. Please try again."
            }
            isLoading = false
        }
    }

    private func loginWithPassword() {
        let user = username.trimmingCharacters(in: .whitespaces)
        let pass = password
        guard !user.isEmpty, !pass.isEmpty else {
            error = "Please enter username and password"
            return
        }

        isLoading = true
        error = nil

        Task {
            do {
                let response = try await APIService.shared.login(username: user, password: pass)
                let resolvedPhoto = APIService.resolvePhotoUrl(response.photoUrl)
                await AuthStorage.shared.saveAuth(
                    userId: response.userId,
                    token: response.token,
                    userName: response.userFirstName,
                    photoUrl: resolvedPhoto
                )
                appState.setAuth(
                    userId: response.userId,
                    token: response.token,
                    userName: response.userFirstName,
                    photoUrl: resolvedPhoto
                )
            } catch {
                self.error = error.localizedDescription
            }
            isLoading = false
        }
    }
}

#Preview {
    LoginScreen()
        .environmentObject(AppState())
}
