//
//  MessageCenterViewModel.swift
//  suixinkan
//
//  Created by Codex on 2026/6/25.
//

import Foundation
import Combine

@MainActor
/// 消息中心 ViewModel，负责消息分页、筛选、已读和删除。
final class MessageCenterViewModel: ObservableObject {
    @Published var messages: [MessageItem] = []
    @Published var selectedFilter: MessageFilter = .all
    @Published var isLoading = false
    @Published var isLoadingMore = false
    @Published var loadFailed = false
    @Published var loadFailureReason: String?
    @Published var message: String?

    @Published private(set) var hasMoreMessages = false
    @Published private(set) var lastId = 0
    private let pageSize = 20

    /// 未读消息数量。
    var unreadCount: Int {
        messages.filter { !$0.isRead }.count
    }

    /// 当前筛选说明。
    var filterDescription: String {
        selectedFilter == .all ? "显示全部消息" : "仅显示未读消息"
    }

    /// 切换筛选并重新加载首屏。
    func selectFilter(_ filter: MessageFilter, api: any MessageCenterServing) async {
        guard selectedFilter != filter else { return }
        selectedFilter = filter
        await reloadFirstPage(api: api)
    }

    /// 重新加载首屏消息，失败时清空旧数据。
    func reloadFirstPage(api: any MessageCenterServing) async {
        isLoading = true
        loadFailed = false
        loadFailureReason = nil
        message = nil
        defer { isLoading = false }

        do {
            let response = try await api.messageList(lastId: 0, limit: pageSize, unread: selectedFilter.rawValue)
            messages = mapMessages(response.items)
            hasMoreMessages = response.hasMore
            lastId = response.lastId
        } catch {
            clearMessages()
            loadFailed = true
            loadFailureReason = error.localizedDescription
            message = error.localizedDescription
        }
    }

    /// 加载更多消息，失败时保留当前数据和分页状态。
    func loadMore(api: any MessageCenterServing) async {
        guard hasMoreMessages, !isLoadingMore, !isLoading else { return }
        isLoadingMore = true
        message = nil
        defer { isLoadingMore = false }

        do {
            let response = try await api.messageList(lastId: lastId, limit: pageSize, unread: selectedFilter.rawValue)
            messages.append(contentsOf: mapMessages(response.items))
            messages = deduplicatedAndSorted(messages)
            hasMoreMessages = response.hasMore
            lastId = response.lastId
        } catch {
            message = error.localizedDescription
        }
    }

    /// 标记单条消息为已读，接口成功后再更新本地状态。
    func markAsRead(api: any MessageCenterServing, item: MessageItem) async throws {
        guard !item.isRead, let msgId = item.msgId else { return }
        try await api.messageRead(id: msgId)
        guard let index = messages.firstIndex(where: { $0.id == item.id }) else { return }
        messages[index].isRead = true
    }

    /// 将当前列表中的未读消息逐条标记为已读。
    func markAllAsRead(api: any MessageCenterServing) async throws {
        let original = messages
        do {
            for item in messages where !item.isRead {
                if let msgId = item.msgId {
                    try await api.messageRead(id: msgId)
                }
            }
            messages = messages.map { item in
                var next = item
                next.isRead = true
                return next
            }
        } catch {
            messages = original
            throw error
        }
    }

    /// 删除消息，接口成功后再移除本地列表。
    func deleteMessage(api: any MessageCenterServing, item: MessageItem) async throws {
        if let msgId = item.msgId {
            try await api.messageDelete(id: msgId)
        }
        messages.removeAll { $0.id == item.id }
    }

    /// 将后端实体转换为页面展示实体。
    func mapMessages(_ source: [MessageEntity]) -> [MessageItem] {
        source.map { item in
            MessageItem(
                id: "msg_\(item.id)",
                msgId: item.id,
                title: item.title.trimmingCharacters(in: .whitespacesAndNewlines).nonEmpty
                    ?? item.typeName.trimmingCharacters(in: .whitespacesAndNewlines).nonEmpty
                    ?? "系统通知",
                detail: item.content,
                time: item.pushAt.trimmingCharacters(in: .whitespacesAndNewlines).nonEmpty
                    ?? item.createdAt.trimmingCharacters(in: .whitespacesAndNewlines).nonEmpty
                    ?? "0000-00-00 00:00",
                isRead: item.isRead,
                type: Self.messageType(from: item.type)
            )
        }
    }

    /// 将后端类型映射为页面消息类型。
    static func messageType(from value: Int) -> MessageType {
        switch value {
        case 1:
            return .order
        case 2:
            return .writeOff
        default:
            return .system
        }
    }

    private func deduplicatedAndSorted(_ source: [MessageItem]) -> [MessageItem] {
        var unique: [String: MessageItem] = [:]
        for item in source {
            unique[item.id] = item
        }
        return unique.values.sorted { $0.time > $1.time }
    }

    private func clearMessages() {
        messages = []
        hasMoreMessages = false
        lastId = 0
        isLoadingMore = false
    }
}

private extension String {
    var nonEmpty: String? {
        isEmpty ? nil : self
    }
}
