import SwiftUI

struct EditPrivacyView: View {
    @State private var profilePermissions = ProfilePermissionsState()
    @State private var isLoading = false
    @State private var loadError: String?
    @State private var isSaving = false
    @State private var alertData: AlertData?

    private let profileService = ProfileService()

    private var privacyScopeOptions: [PrivacyScope] { PrivacyScope.allCases }

    private var autoDeleteAccountEnabled: Binding<Bool> {
        Binding(
            get: { profilePermissions.autoDeleteAfterDays != nil },
            set: { newValue in
                profilePermissions.autoDeleteAfterDays = newValue ? (profilePermissions.autoDeleteAfterDays ?? 30) : nil
            }
        )
    }

    private var autoDeleteAccountBinding: Binding<Int> {
        Binding(
            get: { profilePermissions.autoDeleteAfterDays ?? 30 },
            set: { profilePermissions.autoDeleteAfterDays = min(max($0, 1), 365) }
        )
    }

    private var autoDeleteTimerEnabled: Binding<Bool> {
        Binding(
            get: { profilePermissions.maxMessageAutoDeleteSeconds != nil },
            set: { newValue in
                profilePermissions.maxMessageAutoDeleteSeconds = newValue ? (profilePermissions.maxMessageAutoDeleteSeconds ?? 30) : nil
            }
        )
    }

    private var autoDeleteTimerBinding: Binding<Int> {
        Binding(
            get: { profilePermissions.maxMessageAutoDeleteSeconds ?? 30 },
            set: { profilePermissions.maxMessageAutoDeleteSeconds = min(max($0, 5), 86400) }
        )
    }

    var body: some View {
        Form {
            if isLoading {
                Section {
                    ProgressView()
                        .frame(maxWidth: .infinity, alignment: .center)
                }
            } else if let loadError {
                Section {
                    Text(loadError)
                        .foregroundColor(.red)
                        .frame(maxWidth: .infinity, alignment: .center)
                }
            }

            if !isLoading && loadError == nil {
                Section(header: Text(NSLocalizedString("Профиль и поиск", comment: ""))) {
                    Toggle(NSLocalizedString("Разрешить поиск профиля", comment: ""), isOn: $profilePermissions.isSearchable)
                    Toggle(NSLocalizedString("Разрешить пересылку сообщений", comment: ""), isOn: $profilePermissions.allowMessageForwarding)
                    Toggle(NSLocalizedString("Принимать сообщения от незнакомцев", comment: ""), isOn: $profilePermissions.allowMessagesFromNonContacts)
                }
                
                Section(header: Text(NSLocalizedString("Видимость и контент", comment: ""))) {
                    Toggle(NSLocalizedString("Показывать фото не-контактам", comment: ""), isOn: $profilePermissions.showProfilePhotoToNonContacts)
                    Toggle(NSLocalizedString("Показывать био не-контактам", comment: ""), isOn: $profilePermissions.showBioToNonContacts)
                    Toggle(NSLocalizedString("Показывать сторисы не-контактам", comment: ""), isOn: $profilePermissions.showStoriesToNonContacts)
                    
                    privacyScopePicker(
                        title: NSLocalizedString("Видимость статуса 'был в сети'", comment: ""),
                        selection: $profilePermissions.lastSeenVisibility
                    )
                }
                
                Section(header: Text(NSLocalizedString("Приглашения и звонки", comment: ""))) {
                    privacyScopePicker(
                        title: NSLocalizedString("Кто может приглашать в паблики", comment: ""),
                        selection: $profilePermissions.publicInvitePermission
                    )

                    privacyScopePicker(
                        title: NSLocalizedString("Кто может приглашать в беседы", comment: ""),
                        selection: $profilePermissions.groupInvitePermission
                    )

                    privacyScopePicker(
                        title: NSLocalizedString("Кто может звонить", comment: ""),
                        selection: $profilePermissions.callPermission
                    )
                }
                
                Section(header: Text(NSLocalizedString("Чаты и хранение", comment: ""))) {
                    Toggle(NSLocalizedString("Разрешить хранить чаты на сервере", comment: ""), isOn: $profilePermissions.allowServerChats)
                }
                
                Section(header: Text(NSLocalizedString("Приватные чаты", comment: ""))) {
                    Toggle(NSLocalizedString("Принудительное включение автоудаления сообщений", comment: ""), isOn: $profilePermissions.forceAutoDeleteMessagesInPrivate)
                    Toggle(NSLocalizedString("Ограничить таймер автоудаления (максимум)", comment: ""), isOn: autoDeleteTimerEnabled)
                    
                    if autoDeleteTimerEnabled.wrappedValue {
                        Stepper(value: autoDeleteTimerBinding, in: 5...86400, step: 5) {
                            Text("\(NSLocalizedString("Максимальное время автоудаления", comment: "")): \(formattedAutoDeleteSeconds(autoDeleteTimerBinding.wrappedValue))")
                        }
                    }
                }
                
                Section(header: Text(NSLocalizedString("Автоудаление аккаунта", comment: ""))) {
                    Toggle(NSLocalizedString("Включить автоудаление аккаунта", comment: ""), isOn: autoDeleteAccountEnabled)
                    
                    if autoDeleteAccountEnabled.wrappedValue {
                        Stepper(value: autoDeleteAccountBinding, in: 1...365) {
                            Text(String(format: NSLocalizedString("Удалять аккаунт через %lld дн.", comment: ""), autoDeleteAccountBinding.wrappedValue))

                        }
                    }
                }
                
                Section {
                    Button {
                        Task {
                            await saveProfile()
                        }
                    } label: {
                        if isSaving {
                            ProgressView()
                                .frame(maxWidth: .infinity, alignment: .center)
                        } else {
                            Text(NSLocalizedString("Сохранить изменения", comment: ""))
                                .frame(maxWidth: .infinity, alignment: .center)
                        }
                    }
                    .disabled(isLoading || isSaving)
                }
                
                Section {
                    Button(role: .destructive) {
                        profilePermissions = ProfilePermissionsState()
                        if AppConfig.DEBUG {print("Настройки приватности сброшены к значениям по умолчанию")}
                    } label: {
                        Text(NSLocalizedString("Сбросить по умолчанию", comment: ""))
                            .frame(maxWidth: .infinity, alignment: .center)
                    }
                }
            }
        }
        .alert(item: $alertData) { data in
            Alert(
                title: Text(data.kind == .success
                             ? NSLocalizedString("Готово", comment: "Profile update success title")
                             : NSLocalizedString("Ошибка", comment: "Profile update error title")),
                message: Text(data.message),
                dismissButton: .default(Text(NSLocalizedString("OK", comment: "Profile update alert button"))) {
                    alertData = nil
                }
            )
        }
        .navigationTitle(NSLocalizedString("Настройки приватности", comment: ""))
        .task {
            await loadProfile()
        }
    }

    private func formattedAutoDeleteSeconds(_ value: Int) -> String {
        let secondsString = "\(value) сек."

        switch value {
        case ..<60:
            return secondsString
        case 60..<3600:
            let minutes = value / 60
            return "\(secondsString) (≈ \(minutes) мин.)"
        default:
            let hours = Double(value) / 3600.0
            let formattedHours: String
            if hours.truncatingRemainder(dividingBy: 1) == 0 {
                formattedHours = String(format: "%.0f", hours)
            } else {
                formattedHours = String(format: "%.1f", hours)
            }
            return "\(secondsString) (≈ \(formattedHours) ч.)"
        }
    }

    @ViewBuilder
    private func privacyScopePicker(title: String, selection: Binding<Int>) -> some View {
        VStack(alignment: .leading, spacing: 6) {
            Text(title)
                .font(.body)
                .foregroundColor(.primary)

            Picker("", selection: selection) {
                ForEach(privacyScopeOptions) { scope in
                    Text(scope.title).tag(scope.rawValue)
                }
            }
            .pickerStyle(.segmented)
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding(.vertical, 4)
    }
}

private enum PrivacyScope: Int, CaseIterable, Identifiable {
    case everyone = 0
    case contacts = 1
    case nobody = 2

    var id: Int { rawValue }

    var title: String {
        switch self {
        case .everyone:
            return NSLocalizedString("Все", comment: "")
        case .contacts:
            return NSLocalizedString("Контакты", comment: "")
        case .nobody:
            return NSLocalizedString("Никто", comment: "")
        }
    }
}

struct ProfilePermissionsState: Codable, Equatable {
    var isSearchable: Bool = true
    var allowMessageForwarding: Bool = true
    var allowMessagesFromNonContacts: Bool = true
    var showProfilePhotoToNonContacts: Bool = true
    var lastSeenVisibility: Int = PrivacyScope.everyone.rawValue
    var showBioToNonContacts: Bool = true
    var showStoriesToNonContacts: Bool = true
    var allowServerChats: Bool = true
    var publicInvitePermission: Int = PrivacyScope.everyone.rawValue
    var groupInvitePermission: Int = PrivacyScope.everyone.rawValue
    var callPermission: Int = PrivacyScope.everyone.rawValue
    var forceAutoDeleteMessagesInPrivate: Bool = false
    var maxMessageAutoDeleteSeconds: Int? = nil
    var autoDeleteAfterDays: Int? = nil
}

extension ProfilePermissionsState {
    init(payload: ProfilePermissionsPayload) {
        self.isSearchable = payload.isSearchable
        self.allowMessageForwarding = payload.allowMessageForwarding
        self.allowMessagesFromNonContacts = payload.allowMessagesFromNonContacts
        self.showProfilePhotoToNonContacts = payload.showProfilePhotoToNonContacts
        self.lastSeenVisibility = payload.lastSeenVisibility
        self.showBioToNonContacts = payload.showBioToNonContacts
        self.showStoriesToNonContacts = payload.showStoriesToNonContacts
        self.allowServerChats = payload.allowServerChats
        self.publicInvitePermission = payload.publicInvitePermission
        self.groupInvitePermission = payload.groupInvitePermission
        self.callPermission = payload.callPermission
        self.forceAutoDeleteMessagesInPrivate = payload.forceAutoDeleteMessagesInPrivate
        self.maxMessageAutoDeleteSeconds = payload.maxMessageAutoDeleteSeconds
        self.autoDeleteAfterDays = payload.autoDeleteAfterDays
    }
}

private extension ProfilePermissionsState {
    var requestPayload: ProfilePermissionsRequestPayload {
        ProfilePermissionsRequestPayload(
            isSearchable: isSearchable,
            allowMessageForwarding: allowMessageForwarding,
            allowMessagesFromNonContacts: allowMessagesFromNonContacts,
            showProfilePhotoToNonContacts: showProfilePhotoToNonContacts,
            lastSeenVisibility: lastSeenVisibility,
            showBioToNonContacts: showBioToNonContacts,
            showStoriesToNonContacts: showStoriesToNonContacts,
            allowServerChats: allowServerChats,
            publicInvitePermission: publicInvitePermission,
            groupInvitePermission: groupInvitePermission,
            callPermission: callPermission,
            forceAutoDeleteMessagesInPrivate: forceAutoDeleteMessagesInPrivate,
            maxMessageAutoDeleteSeconds: maxMessageAutoDeleteSeconds,
            autoDeleteAfterDays: autoDeleteAfterDays
        )
    }
}

private extension EditPrivacyView {
    func saveProfile() async {
        let shouldProceed = await MainActor.run { () -> Bool in
            if isSaving {
                return false
            }
            isSaving = true
            return true
        }

        guard shouldProceed else { return }

        do {
            let requestPayload = ProfileUpdateRequestPayload(profilePermissions: profilePermissions.requestPayload)
            let responseMessage = try await profileService.updateProfile(requestPayload)
            let fallback = NSLocalizedString("Настройки приватности обновлены.", comment: "Profile update success fallback")
            let message = responseMessage.isEmpty ? fallback : responseMessage

            await MainActor.run {
                alertData = AlertData(kind: .success, message: message)
                isSaving = false
            }
        } catch {
            let message: String
            if let error = error as? LocalizedError, let description = error.errorDescription {
                message = description
            } else {
                message = error.localizedDescription
            }

            await MainActor.run {
                alertData = AlertData(kind: .error, message: message)
                isSaving = false
            }
        }
    }

    func loadProfile() async {
        await MainActor.run {
            if !isLoading {
                isLoading = true
                loadError = nil
            }
        }

        do {
            let profile = try await profileService.fetchMyProfile()
            await MainActor.run {
                profilePermissions = ProfilePermissionsState(payload: profile.profilePermissions)
                isLoading = false
            }
        } catch {
            let message: String
            if let error = error as? LocalizedError, let description = error.errorDescription {
                message = description
            } else {
                message = error.localizedDescription
            }

            await MainActor.run {
                loadError = message
                isLoading = false
            }
        }
    }
}

private struct AlertData: Identifiable {
    enum Kind {
        case success
        case error
    }

    let id = UUID()
    let kind: Kind
    let message: String
}
