import SwiftUI

struct BlockedUsersView: View {
    @State private var blockedUsers: [BlockedUser] = []
    @State private var isLoading = false
    @State private var loadError: String?
    @State private var pendingUnblock: BlockedUser?
    @State private var showUnblockConfirmation = false
    @State private var removingUserIds: Set<UUID> = []
    @State private var activeAlert: ActiveAlert?

    private let blockedUsersService = BlockedUsersService()

    var body: some View {
        List {
            if isLoading && blockedUsers.isEmpty {
                loadingState
            } else if let loadError, blockedUsers.isEmpty {
                errorState(loadError)
            } else if blockedUsers.isEmpty {
                emptyState
            } else {
                Section(header: Text(NSLocalizedString("Заблокированные", comment: ""))) {
                    ForEach(blockedUsers) { user in
                        HStack(spacing: 12) {
                            Circle()
                                .fill(Color.accentColor.opacity(0.15))
                                .frame(width: 44, height: 44)
                                .overlay(
                                    Text(user.initials)
                                        .font(.headline)
                                        .foregroundColor(.accentColor)
                                )
                            VStack(alignment: .leading, spacing: 4) {
                                Text(user.displayName)
                                    .font(.body)
                                if let handle = user.handle {
                                    Text(handle)
                                        .font(.caption)
                                        .foregroundColor(.secondary)
                                }
                            }
                            Spacer()
                        }
                        .padding(.vertical, 4)
                        .swipeActions(edge: .trailing) {
                            Button(role: .destructive) {
                                pendingUnblock = user
                                showUnblockConfirmation = true
                            } label: {
                                Label(NSLocalizedString("Разблокировать", comment: ""), systemImage: "person.crop.circle.badge.xmark")
                            }
                            .disabled(removingUserIds.contains(user.id))
                        }
                    }
                }
            }
        }
        .navigationTitle(NSLocalizedString("Заблокированные", comment: ""))
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .navigationBarTrailing) {
                Button {
                    activeAlert = .addPlaceholder
                } label: {
                    Image(systemName: "plus")
                }
            }
        }
        .task {
            await loadBlockedUsers()
        }
//        .refreshable {
//            await loadBlockedUsers()
//        }
        .alert(item: $activeAlert) { alert in
            switch alert {
            case .addPlaceholder:
                return Alert(
                    title: Text(NSLocalizedString("Скоро", comment: "Add blocked user placeholder title")),
                    message: Text(NSLocalizedString("Добавление новых блокировок появится позже.", comment: "Add blocked user placeholder message")),
                    dismissButton: .default(Text(NSLocalizedString("OK", comment: "Common OK")))
                )
            case .error(_, let message):
                return Alert(
                    title: Text(NSLocalizedString("Ошибка", comment: "Common error title")),
                    message: Text(message),
                    dismissButton: .default(Text(NSLocalizedString("OK", comment: "Common OK")))
                )
            }
        }
        .confirmationDialog(
            NSLocalizedString("Удалить из заблокированных?", comment: "Unblock confirmation title"),
            isPresented: $showUnblockConfirmation,
            presenting: pendingUnblock
        ) { user in
            Button(NSLocalizedString("Разблокировать", comment: "Unblock confirmation action"), role: .destructive) {
                pendingUnblock = nil
                showUnblockConfirmation = false
                Task {
                    await unblock(user)
                }
            }
            Button(NSLocalizedString("Отмена", comment: "Common cancel"), role: .cancel) {
                pendingUnblock = nil
                showUnblockConfirmation = false
            }
        } message: { user in
            Text(String(format: NSLocalizedString("Пользователь \"%1$@\" будет удалён из списка заблокированных.", comment: "Unblock confirmation message"), user.displayName))
        }
    }

    private var emptyState: some View {
        VStack(spacing: 12) {
            Image(systemName: "hand.raised")
                .font(.system(size: 48))
                .foregroundColor(.secondary)
            Text(NSLocalizedString("У вас нет заблокированных пользователей", comment: ""))
                .font(.headline)
                .multilineTextAlignment(.center)
//            Text(NSLocalizedString("Заблокируйте аккаунт, чтобы скрыть его сообщения и взаимодействия", comment: ""))
//                .font(.subheadline)
//                .foregroundColor(.secondary)
//                .multilineTextAlignment(.center)
        }
        .frame(maxWidth: .infinity, alignment: .center)
        .padding(.vertical, 32)
        .listRowInsets(EdgeInsets(top: 16, leading: 16, bottom: 16, trailing: 16))
        .listRowSeparator(.hidden)
    }

    private var loadingState: some View {
        Section {
            ProgressView()
                .frame(maxWidth: .infinity, alignment: .center)
        }
    }

    private func errorState(_ message: String) -> some View {
        Section {
            Text(message)
                .foregroundColor(.red)
                .frame(maxWidth: .infinity, alignment: .center)
        }
    }

    @MainActor
    private func loadBlockedUsers() async {
        if isLoading {
            return
        }

        isLoading = true
        loadError = nil

        do {
            let payloads = try await blockedUsersService.fetchBlockedUsers()
            blockedUsers = payloads.map(BlockedUser.init)
        } catch {
            loadError = error.localizedDescription
            activeAlert = .error(message: error.localizedDescription)
            if AppConfig.DEBUG { print("[BlockedUsersView] load blocked users failed: \(error)") }
        }

        isLoading = false
    }

    @MainActor
    private func unblock(_ user: BlockedUser) async {
        guard !removingUserIds.contains(user.id) else { return }

        removingUserIds.insert(user.id)
        defer { removingUserIds.remove(user.id) }

        do {
            _ = try await blockedUsersService.remove(userId: user.id)
            blockedUsers.removeAll { $0.id == user.id }
        } catch {
            activeAlert = .error(message: error.localizedDescription)
            if AppConfig.DEBUG { print("[BlockedUsersView] unblock failed: \(error)") }
        }
    }
}

private struct BlockedUser: Identifiable, Equatable {
    let id: UUID
    let login: String
    let fullName: String?
    let customName: String?
    let createdAt: Date

    private(set) var displayName: String
    private(set) var handle: String?

    var initials: String {
        let components = displayName.split(separator: " ")
        let nameInitials = components.prefix(2).compactMap { $0.first }
        if !nameInitials.isEmpty {
            return nameInitials
                .map { String($0).uppercased() }
                .joined()
        }

        if let handle {
            let filtered = handle.filter { $0.isLetter }.prefix(2)
            if !filtered.isEmpty {
                return filtered.uppercased()
            }
        }

        return "??"
    }

    init(payload: BlockedUserPayload) {
        self.id = payload.userId
        self.login = payload.login
        self.fullName = payload.fullName
        self.customName = payload.customName
        self.createdAt = payload.createdAt

        if let customName = payload.customName, !customName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
            self.displayName = customName
        } else if let fullName = payload.fullName, !fullName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
            self.displayName = fullName
        } else {
            self.displayName = payload.login
        }

        if !payload.login.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
            self.handle = "@\(payload.login)"
        } else {
            self.handle = nil
        }
    }
}

private enum ActiveAlert: Identifiable {
    case addPlaceholder
    case error(id: UUID = UUID(), message: String)

    var id: String {
        switch self {
        case .addPlaceholder:
            return "addPlaceholder"
        case .error(let id, _):
            return id.uuidString
        }
    }
}
