import Foundation

final class PrivateChatsViewModel: ObservableObject {
    @Published private(set) var chats: [PrivateChatListItem] = []
    @Published private(set) var isInitialLoading: Bool = false
    @Published private(set) var isLoadingMore: Bool = false
    @Published var errorMessage: String?

    private let chatService: ChatService
    private let pageSize: Int
    private var offset: Int = 0
    private var hasMore: Bool = true

    init(chatService: ChatService = ChatService(), pageSize: Int = 20) {
        self.chatService = chatService
        self.pageSize = pageSize
    }

    func loadInitialChats(force: Bool = false) {
        guard !isInitialLoading else { return }
        if !force && !chats.isEmpty { return }

        isInitialLoading = true
        errorMessage = nil
        let previousOffset = offset
        let previousHasMore = hasMore
        offset = 0
        hasMore = true

        chatService.fetchPrivateChats(offset: 0, limit: pageSize) { [weak self] result in
            guard let self else { return }
            self.isInitialLoading = false
            defer {
                NotificationCenter.default.post(name: .chatsReloadCompleted, object: nil)
            }

            switch result {
            case .success(let data):
                self.chats = data.items
                self.offset = data.items.count
                self.hasMore = data.hasMore
            case .failure(let error):
                self.errorMessage = self.message(for: error)
                self.offset = previousOffset
                self.hasMore = previousHasMore
            }
        }
    }

    func refresh() {
        loadInitialChats(force: true)
    }

    func loadMoreIfNeeded(currentItem item: PrivateChatListItem) {
        guard hasMore, !isLoadingMore, item.id == chats.last?.id else { return }

        isLoadingMore = true

        chatService.fetchPrivateChats(offset: offset, limit: pageSize) { [weak self] result in
            guard let self else { return }
            self.isLoadingMore = false

            switch result {
            case .success(let data):
                self.chats.append(contentsOf: data.items)
                self.offset = self.chats.count
                self.hasMore = data.hasMore
            case .failure(let error):
                self.errorMessage = self.message(for: error)
            }
        }
    }

    private func message(for error: Error) -> String {
        if let chatError = error as? ChatServiceError {
            return chatError.errorDescription ?? NSLocalizedString("Не удалось загрузить чаты.", comment: "")
        }

        if let networkError = error as? NetworkError {
            switch networkError {
            case .unauthorized:
                return NSLocalizedString("Сессия истекла. Войдите снова.", comment: "")
            case .invalidURL, .noResponse:
                return NSLocalizedString("Ошибка соединения с сервером.", comment: "")
            case .network(let underlying):
                return String(format: NSLocalizedString("Ошибка сети: %@", comment: ""), underlying.localizedDescription)
            case .server(let statusCode, _):
                return String(format: NSLocalizedString("Ошибка сервера (%@).", comment: ""), "\(statusCode)")
            }
        }

        return NSLocalizedString("Неизвестная ошибка. Попробуйте позже.", comment: "")
    }
}
