import SwiftUI
import ComposeApp

struct ResidenceFormView: View {
    let existingResidence: ResidenceResponse?
    @Binding var isPresented: Bool
    var onSuccess: (() -> Void)?
    @StateObject private var viewModel = ResidenceViewModel()
    @ObservedObject private var dataManager = DataManagerObservable.shared
    @FocusState private var focusedField: Field?

    // Lookups from DataManagerObservable
    private var residenceTypes: [ResidenceType] { dataManager.residenceTypes }

    // User management state
    @State private var users: [ResidenceUserResponse] = []
    @State private var isLoadingUsers = false
    @State private var userToRemove: ResidenceUserResponse?
    @State private var showRemoveUserConfirmation = false

    // Check if current user is the owner
    private var isCurrentUserOwner: Bool {
        guard let residence = existingResidence,
              let currentUser = dataManager.currentUser else { return false }
        return Int(residence.ownerId) == Int(currentUser.id)
    }

    // Form fields
    @State private var name: String = ""
    @State private var selectedPropertyType: ResidenceType?
    @State private var streetAddress: String = ""
    @State private var apartmentUnit: String = ""
    @State private var city: String = ""
    @State private var stateProvince: String = ""
    @State private var postalCode: String = ""
    @State private var country: String = "USA"
    @State private var bedrooms: String = ""
    @State private var bathrooms: String = ""
    @State private var squareFootage: String = ""
    @State private var lotSize: String = ""
    @State private var yearBuilt: String = ""
    @State private var description: String = ""
    @State private var isPrimary: Bool = false

    // Validation errors
    @State private var nameError: String = ""

    enum Field {
        case name, streetAddress, apartmentUnit, city, stateProvince, postalCode, country
        case bedrooms, bathrooms, squareFootage, lotSize, yearBuilt, description
    }

    private var isEditMode: Bool {
        existingResidence != nil
    }

    private var canSave: Bool {
        !name.isEmpty
    }

    var body: some View {
        NavigationStack {
            Form {
                // Property Details
                Section {
                    TextField(L10n.Residences.propertyName, text: $name)
                        .focused($focusedField, equals: .name)
                        .accessibilityIdentifier(AccessibilityIdentifiers.Residence.nameField)

                    if !nameError.isEmpty {
                        FieldError(message: nameError)
                    }

                    Picker(L10n.Residences.propertyType, selection: $selectedPropertyType) {
                        Text(L10n.Residences.selectType).tag(nil as ResidenceType?)
                        ForEach(residenceTypes, id: \.self) { type in
                            Text(type.name).tag(type as ResidenceType?)
                        }
                    }
                    .accessibilityIdentifier(AccessibilityIdentifiers.Residence.propertyTypePicker)
                } header: {
                    Text(L10n.Residences.propertyDetails)
                        .accessibilityAddTraits(.isHeader)
                } footer: {
                    Text(L10n.Residences.nameRequired)
                        .font(.caption)
                        .foregroundColor(Color.appError)
                }
                .sectionBackground()

                // Address
                Section {
                    TextField(L10n.Residences.streetAddress, text: $streetAddress)
                        .focused($focusedField, equals: .streetAddress)
                        .textContentType(.streetAddressLine1)
                        .submitLabel(.next)
                        .onSubmit { focusedField = .apartmentUnit }
                        .accessibilityIdentifier(AccessibilityIdentifiers.Residence.streetAddressField)

                    TextField(L10n.Residences.apartmentUnit, text: $apartmentUnit)
                        .focused($focusedField, equals: .apartmentUnit)
                        .textContentType(.streetAddressLine2)
                        .submitLabel(.next)
                        .onSubmit { focusedField = .city }
                        .accessibilityIdentifier(AccessibilityIdentifiers.Residence.apartmentUnitField)

                    TextField(L10n.Residences.city, text: $city)
                        .focused($focusedField, equals: .city)
                        .textContentType(.addressCity)
                        .submitLabel(.next)
                        .onSubmit { focusedField = .stateProvince }
                        .accessibilityIdentifier(AccessibilityIdentifiers.Residence.cityField)

                    TextField(L10n.Residences.stateProvince, text: $stateProvince)
                        .focused($focusedField, equals: .stateProvince)
                        .textContentType(.addressState)
                        .submitLabel(.next)
                        .onSubmit { focusedField = .postalCode }
                        .accessibilityIdentifier(AccessibilityIdentifiers.Residence.stateProvinceField)

                    TextField(L10n.Residences.postalCode, text: $postalCode)
                        .focused($focusedField, equals: .postalCode)
                        .textContentType(.postalCode)
                        .keyboardType(.numberPad)
                        .accessibilityIdentifier(AccessibilityIdentifiers.Residence.postalCodeField)

                    TextField(L10n.Residences.country, text: $country)
                        .focused($focusedField, equals: .country)
                        .textContentType(.countryName)
                        .submitLabel(.done)
                        .onSubmit { focusedField = nil }
                        .accessibilityIdentifier(AccessibilityIdentifiers.Residence.countryField)
                } header: {
                    Text(L10n.Residences.address)
                        .accessibilityAddTraits(.isHeader)
                }
                .sectionBackground()

                // Property Features
                Section {
                    TextField(L10n.Residences.bedrooms, text: $bedrooms)
                        .keyboardType(.numberPad)
                        .focused($focusedField, equals: .bedrooms)
                        .accessibilityIdentifier(AccessibilityIdentifiers.Residence.bedroomsField)

                    TextField(L10n.Residences.bathrooms, text: $bathrooms)
                        .keyboardType(.decimalPad)
                        .focused($focusedField, equals: .bathrooms)
                        .accessibilityIdentifier(AccessibilityIdentifiers.Residence.bathroomsField)

                    TextField(L10n.Residences.squareFootage, text: $squareFootage)
                        .keyboardType(.numberPad)
                        .focused($focusedField, equals: .squareFootage)
                        .accessibilityIdentifier(AccessibilityIdentifiers.Residence.squareFootageField)

                    TextField(L10n.Residences.lotSize, text: $lotSize)
                        .keyboardType(.decimalPad)
                        .focused($focusedField, equals: .lotSize)
                        .accessibilityIdentifier(AccessibilityIdentifiers.Residence.lotSizeField)

                    TextField(L10n.Residences.yearBuilt, text: $yearBuilt)
                        .keyboardType(.numberPad)
                        .focused($focusedField, equals: .yearBuilt)
                        .accessibilityIdentifier(AccessibilityIdentifiers.Residence.yearBuiltField)
                } header: {
                    Text(L10n.Residences.propertyFeatures)
                        .accessibilityAddTraits(.isHeader)
                }
                .sectionBackground()

                // Additional Details
                Section {
                    TextField(L10n.Residences.description, text: $description, axis: .vertical)
                        .lineLimit(3...6)
                        .accessibilityIdentifier(AccessibilityIdentifiers.Residence.descriptionField)

                    Toggle(L10n.Residences.primaryResidence, isOn: $isPrimary)
                        .accessibilityIdentifier(AccessibilityIdentifiers.Residence.isPrimaryToggle)
                } header: {
                    Text(L10n.Residences.additionalDetails)
                        .accessibilityAddTraits(.isHeader)
                }
                .sectionBackground()

                // Users Section (edit mode only, owner only)
                if isEditMode && isCurrentUserOwner {
                    Section {
                        if isLoadingUsers {
                            HStack {
                                Spacer()
                                ProgressView()
                                Spacer()
                            }
                        } else if users.isEmpty {
                            Text("No shared users")
                                .foregroundColor(Color.appTextSecondary)
                        } else {
                            ForEach(users, id: \.id) { user in
                                HStack {
                                    VStack(alignment: .leading, spacing: 2) {
                                        HStack(spacing: 6) {
                                            Text(user.username)
                                                .font(.body.weight(.medium))
                                            if user.id == existingResidence?.ownerId {
                                                Text("Owner")
                                                    .font(.caption2.weight(.bold))
                                                    .foregroundColor(Color.appTextOnPrimary)
                                                    .padding(.horizontal, 6)
                                                    .padding(.vertical, 2)
                                                    .background(Color.appPrimary)
                                                    .clipShape(Capsule())
                                            }
                                        }
                                        if !user.email.isEmpty {
                                            Text(user.email)
                                                .font(.caption)
                                                .foregroundColor(Color.appTextSecondary)
                                        }
                                    }
                                    Spacer()
                                    if user.id != existingResidence?.ownerId {
                                        Button {
                                            userToRemove = user
                                            showRemoveUserConfirmation = true
                                        } label: {
                                            Image(systemName: "trash")
                                                .foregroundColor(Color.appError)
                                        }
                                        .buttonStyle(.plain)
                                    }
                                }
                            }
                        }
                    } header: {
                        Text("Shared Users (\(users.count))")
                    } footer: {
                        Text("Use the share button to invite others")
                            .font(.caption)
                    }
                    .sectionBackground()
                }

                // Error Message
                if let errorMessage = viewModel.errorMessage {
                    Section {
                        HStack(spacing: 8) {
                            Image(systemName: "exclamationmark.triangle.fill")
                                .foregroundColor(Color.appError)
                            Text(errorMessage)
                                .foregroundColor(Color.appError)
                                .font(.subheadline)
                        }
                    }
                    .sectionBackground()
                }
            }
            .listStyle(.plain)
            .scrollContentBackground(.hidden)
            .background(Color.appBackgroundPrimary)
            .navigationTitle(isEditMode ? L10n.Residences.editTitle : L10n.Residences.addTitle)
            .navigationBarTitleDisplayMode(.inline)
            .keyboardDismissToolbar()
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button(L10n.Common.cancel) {
                        isPresented = false
                    }
                    .accessibilityIdentifier(AccessibilityIdentifiers.Residence.formCancelButton)
                }

                ToolbarItem(placement: .confirmationAction) {
                    Button(action: submitForm) {
                        if viewModel.isLoading {
                            ProgressView()
                        } else {
                            Text(isEditMode ? L10n.Common.save : L10n.Common.add)
                        }
                    }
                    .disabled(!canSave || viewModel.isLoading)
                    .accessibilityIdentifier(AccessibilityIdentifiers.Residence.saveButton)
                }
            }
            .onAppear {
                if !isEditMode {
                    AnalyticsManager.shared.trackScreen(.newResidence)
                }
                loadResidenceTypes()
                initializeForm()
                if isEditMode && isCurrentUserOwner {
                    loadUsers()
                }
            }
            .alert("Remove User", isPresented: $showRemoveUserConfirmation) {
                Button("Cancel", role: .cancel) {
                    userToRemove = nil
                }
                Button("Remove", role: .destructive) {
                    if let user = userToRemove {
                        removeUser(user)
                    }
                }
            } message: {
                if let user = userToRemove {
                    Text("Are you sure you want to remove \(user.username) from this residence?")
                }
            }
        }
    }

    private func loadResidenceTypes() {
        Task {
            _ = try? await APILayer.shared.getResidenceTypes(forceRefresh: false)
        }
    }

    private func initializeForm() {
        if let residence = existingResidence {
            name = residence.name
            streetAddress = residence.streetAddress ?? ""
            apartmentUnit = residence.apartmentUnit ?? ""
            city = residence.city ?? ""
            stateProvince = residence.stateProvince ?? ""
            postalCode = residence.postalCode ?? ""
            country = residence.country ?? ""
            bedrooms = residence.bedrooms.map { "\($0)" } ?? ""
            bathrooms = residence.bathrooms.map { "\($0)" } ?? ""
            squareFootage = residence.squareFootage.map { "\($0)" } ?? ""
            lotSize = residence.lotSize.map { "\($0)" } ?? ""
            yearBuilt = residence.yearBuilt.map { "\($0)" } ?? ""
            description = residence.description_ ?? ""
            isPrimary = residence.isPrimary

            if let propertyTypeId = residence.propertyTypeId {
                selectedPropertyType = residenceTypes.first { $0.id == Int32(propertyTypeId) }
            }
        }
    }

    private func validateForm() -> Bool {
        var isValid = true

        if name.isEmpty {
            nameError = L10n.Residences.nameRequired
            isValid = false
        } else {
            nameError = ""
        }

        return isValid
    }

    private func submitForm() {
        guard validateForm() else { return }

        let bedroomsValue: KotlinInt? = {
            guard !bedrooms.isEmpty, let value = Int32(bedrooms) else { return nil }
            return KotlinInt(int: value)
        }()
        let bathroomsValue: KotlinDouble? = {
            guard !bathrooms.isEmpty, let value = Double(bathrooms) else { return nil }
            return KotlinDouble(double: value)
        }()
        let squareFootageValue: KotlinInt? = {
            guard !squareFootage.isEmpty, let value = Int32(squareFootage) else { return nil }
            return KotlinInt(int: value)
        }()
        let lotSizeValue: KotlinDouble? = {
            guard !lotSize.isEmpty, let value = Double(lotSize) else { return nil }
            return KotlinDouble(double: value)
        }()
        let yearBuiltValue: KotlinInt? = {
            guard !yearBuilt.isEmpty, let value = Int32(yearBuilt) else { return nil }
            return KotlinInt(int: value)
        }()

        let propertyTypeValue: KotlinInt? = {
            guard let type = selectedPropertyType else { return nil }
            return KotlinInt(int: Int32(type.id))
        }()

        let request = ResidenceCreateRequest(
            name: name,
            propertyTypeId: propertyTypeValue,
            streetAddress: streetAddress.isEmpty ? nil : streetAddress,
            apartmentUnit: apartmentUnit.isEmpty ? nil : apartmentUnit,
            city: city.isEmpty ? nil : city,
            stateProvince: stateProvince.isEmpty ? nil : stateProvince,
            postalCode: postalCode.isEmpty ? nil : postalCode,
            country: country.isEmpty ? nil : country,
            bedrooms: bedroomsValue,
            bathrooms: bathroomsValue,
            squareFootage: squareFootageValue,
            lotSize: lotSizeValue,
            yearBuilt: yearBuiltValue,
            description: description.isEmpty ? nil : description,
            purchaseDate: nil,
            purchasePrice: nil,
            isPrimary: KotlinBoolean(bool: isPrimary),
            heatingType: nil,
            coolingType: nil,
            waterHeaterType: nil,
            roofType: nil,
            hasPool: nil,
            hasSprinklerSystem: nil,
            hasSeptic: nil,
            hasFireplace: nil,
            hasGarage: nil,
            hasBasement: nil,
            hasAttic: nil,
            exteriorType: nil,
            flooringPrimary: nil,
            landscapingType: nil
        )

        if let residence = existingResidence {
            viewModel.updateResidence(id: residence.id, request: request) { success in
                if success {
                    onSuccess?()
                    isPresented = false
                }
            }
        } else {
            viewModel.createResidence(request: request) { success in
                if success {
                    AnalyticsManager.shared.track(.residenceCreated(type: selectedPropertyType?.name ?? "unknown"))
                    onSuccess?()
                    isPresented = false
                }
            }
        }
    }

    private func loadUsers() {
        guard let residence = existingResidence,
              TokenStorage.shared.getToken() != nil else { return }

        isLoadingUsers = true

        Task {
            do {
                let result = try await APILayer.shared.getResidenceUsers(residenceId: residence.id)

                await MainActor.run {
                    if let successResult = result as? ApiResultSuccess<NSArray>,
                       let responseData = successResult.data as? [ResidenceUserResponse] {
                        self.users = responseData.filter { $0.id != residence.ownerId }
                    }
                    self.isLoadingUsers = false
                }
            } catch {
                await MainActor.run {
                    self.isLoadingUsers = false
                }
            }
        }
    }

    private func removeUser(_ user: ResidenceUserResponse) {
        guard let residence = existingResidence,
              TokenStorage.shared.getToken() != nil else { return }

        Task {
            do {
                let result = try await APILayer.shared.removeUser(residenceId: residence.id, userId: user.id)

                await MainActor.run {
                    if result is ApiResultSuccess<RemoveUserResponse> {
                        self.users.removeAll { $0.id == user.id }
                    }
                    self.userToRemove = nil
                }
            } catch {
                await MainActor.run {
                    self.userToRemove = nil
                }
            }
        }
    }
}

#Preview("Add Mode") {
    ResidenceFormView(existingResidence: nil, isPresented: .constant(true))
}
