//
//  MessageCenterViewModels.swift
//  suixinkan
//

import Foundation

/// 消息中心列表页 ViewModel，负责分页、刷新和未读点击处理。
final class MessageCenterViewModel {
    private(set) var items: [MessageItem] = []
    private(set) var isLoading = false
    private(set) var isRefreshing = false
    private(set) var isLoadingMore = false
    private(set) var isMarkingAllAsRead = false
    private(set) var canLoadMore = false

    var onStateChange: (() -> Void)?
    var onShowMessage: ((String) -> Void)?
    var onOpenDetail: ((MessageItem) -> Void)?
    var onUnreadMessageCountChange: ((Int) -> Void)?

    private let pageSize = 20
    private var lastId = 0

    /// 首次加载消息列表。
    func loadInitial(api: any MessageCenterServing) async {
        await load(reset: true, showLoading: true, api: api)
    }

    /// 下拉刷新消息列表。
    func refresh(api: any MessageCenterServing) async {
        guard !isLoading else { return }
        isRefreshing = true
        notifyStateChange()
        await load(reset: true, showLoading: false, api: api)
    }

    /// 滚动到底部附近时加载更多。
    func loadMoreIfNeeded(lastVisibleIndex: Int, api: any MessageCenterServing) async {
        guard lastVisibleIndex >= items.count - 4 else { return }
        await load(reset: false, showLoading: false, api: api)
    }

    /// 点击消息：未读先标记已读，成功后进入详情；已读直接进入详情。
    func selectMessage(id: Int, api: any MessageCenterServing) async {
        guard let item = items.first(where: { $0.id == id }) else { return }
        if item.isRead {
            onOpenDetail?(item)
            return
        }

        isLoading = true
        notifyStateChange()
        defer {
            isLoading = false
            notifyStateChange()
        }

        do {
            let response = try await api.markAsRead(messageId: id)
            let readItem = item.markedRead()
            items = items.map { $0.id == id ? readItem : $0 }
            notifyUnreadMessageCountChanged(response.unreadCount)
            onOpenDetail?(readItem)
        } catch is CancellationError {
            return
        } catch {
            onShowMessage?("标记已读失败")
        }
    }

    /// 将当前账号的全部消息标记已读，成功时返回服务端最新统计。
    func markAllAsRead(api: any MessageCenterServing) async -> MessageReadAllResponse? {
        guard !isLoading, !isMarkingAllAsRead else { return nil }
        isMarkingAllAsRead = true
        notifyStateChange()
        defer {
            isMarkingAllAsRead = false
            notifyStateChange()
        }

        do {
            let response = try await api.markAllAsRead()
            items = items.map { $0.isRead ? $0 : $0.markedRead() }
            notifyUnreadMessageCountChanged(response.unreadCount)
            onShowMessage?(response.updatedCount > 0 ? "已全部标记为已读" : "暂无未读消息")
            return response
        } catch is CancellationError {
            return nil
        } catch {
            onShowMessage?("全部标记已读失败，请稍后重试")
            return nil
        }
    }

    /// 删除后从本地列表移除消息。
    func removeMessage(id: Int) {
        items.removeAll { $0.id == id }
        notifyStateChange()
    }

    private func load(reset: Bool, showLoading: Bool, api: any MessageCenterServing) async {
        if reset {
            lastId = 0
            canLoadMore = false
        } else {
            guard canLoadMore, !isLoading, !isLoadingMore else { return }
            isLoadingMore = true
        }

        isLoading = showLoading
        notifyStateChange()
        defer {
            isLoading = false
            isRefreshing = false
            isLoadingMore = false
            notifyStateChange()
        }

        do {
            let response = try await api.list(lastId: reset ? 0 : lastId, limit: pageSize, unread: 0)
            lastId = response.lastId
            items = reset ? response.items : items + response.items
            canLoadMore = response.hasMore && response.lastId > 0
        } catch is CancellationError {
            return
        } catch {
            if reset {
                items = []
                lastId = 0
                canLoadMore = false
            }
            onShowMessage?(error.localizedDescription)
        }
    }

    private func notifyStateChange() {
        onStateChange?()
    }

    private func notifyUnreadMessageCountChanged(_ count: Int) {
        let normalizedCount = max(count, 0)
        onUnreadMessageCountChange?(normalizedCount)
        NotificationCenter.default.post(
            name: NotificationName.unreadMessageCountDidChange,
            object: nil,
            userInfo: [NotificationUserInfoKey.unreadCount: normalizedCount]
        )
    }
}

/// 消息详情页 ViewModel，负责删除当前消息。
final class MessageDetailViewModel {
    private(set) var message: MessageItem
    private(set) var isDeleting = false

    var onStateChange: (() -> Void)?
    var onShowMessage: ((String) -> Void)?
    var onDeleted: ((Int) -> Void)?

    /// 初始化消息详情 ViewModel。
    init(message: MessageItem) {
        self.message = message
    }

    /// 删除当前消息。
    func delete(api: any MessageCenterServing) async {
        guard message.id > 0 else {
            onShowMessage?("消息ID无效")
            return
        }

        isDeleting = true
        notifyStateChange()
        defer {
            isDeleting = false
            notifyStateChange()
        }

        do {
            try await api.delete(messageId: message.id)
            onShowMessage?("删除成功")
            onDeleted?(message.id)
        } catch is CancellationError {
            return
        } catch {
            let detail = error.localizedDescription.trimmingCharacters(in: .whitespacesAndNewlines)
            onShowMessage?("删除失败: \(detail.isEmpty ? "请稍后重试" : detail)")
        }
    }

    private func notifyStateChange() {
        onStateChange?()
    }
}
