//
//  ProfileEditViewModel.swift
//  suixinkan
//

import Foundation

/// 资料编辑页 ViewModel，负责头像与昵称的本地编辑与提交保存。
final class ProfileEditViewModel {

    private let initialNickname: String
    private let initialAvatarURL: String

    private(set) var editingNickname = ""
    private(set) var pendingAvatarData: Data?
    private(set) var pendingAvatarFileName: String?
    private(set) var isSaving = false
    private(set) var avatarUploadProgress: Int?

    var onStateChange: (() -> Void)?

    /// 当前展示用的远程头像 URL（未选择新图时使用初始值）。
    var displayAvatarURL: String {
        initialAvatarURL
    }

    /// 使用「我的」页当前展示的快照初始化编辑态。
    init(nickname: String, avatarURL: String) {
        initialNickname = nickname
        initialAvatarURL = avatarURL
        editingNickname = nickname == "未设置昵称" ? "" : nickname
    }

    func updateEditingNickname(_ value: String) {
        editingNickname = value
        notifyStateChange()
    }

    func prepareAvatarImage(data: Data, timestamp: TimeInterval = Date().timeIntervalSince1970) throws {
        let processed = try AvatarImageProcessor.process(data: data, timestamp: timestamp)
        pendingAvatarData = processed.data
        pendingAvatarFileName = processed.fileName
        notifyStateChange()
    }

    /// 提交昵称与头像变更；无变更时不请求网络。
    func saveProfile(api: ProfileAPI, uploader: any OSSUploadServing, scenicId: Int) async throws {
        let nextNickname = editingNickname.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !nextNickname.isEmpty else {
            throw ProfileValidationError.emptyNickname
        }

        let nicknameChanged = nextNickname != initialNickname
        let avatarChanged = pendingAvatarData != nil
        guard nicknameChanged || avatarChanged else { return }

        guard !isSaving else { return }
        isSaving = true
        avatarUploadProgress = avatarChanged ? 1 : nil
        notifyStateChange()
        defer {
            isSaving = false
            avatarUploadProgress = nil
            notifyStateChange()
        }

        let uploadedAvatarURL = try await uploadPendingAvatarIfNeeded(uploader: uploader, scenicId: scenicId)
        if let uploadedAvatarURL {
            try await api.updateUserAvatarURL(uploadedAvatarURL)
        }
        if nicknameChanged {
            try await api.updateUserInfo(nickname: nextNickname)
        }

        AppStore.shared.session.userName = nextNickname
        if let uploadedAvatarURL {
            AppStore.shared.session.avatar = uploadedAvatarURL
        }

        clearPendingAvatar()
        NotificationCenter.default.post(name: NotificationName.userProfileDidUpdate, object: nil)
    }

    private func uploadPendingAvatarIfNeeded(uploader: any OSSUploadServing, scenicId: Int) async throws -> String? {
        guard let pendingAvatarData else { return nil }
        let fileName = pendingAvatarFileName ?? "avatar_\(Int(Date().timeIntervalSince1970)).jpg"
        return try await uploader.uploadUserAvatar(data: pendingAvatarData, fileName: fileName, scenicId: scenicId) { [weak self] progress in
            self?.avatarUploadProgress = progress
            self?.notifyStateChange()
        }
    }

    private func clearPendingAvatar() {
        pendingAvatarData = nil
        pendingAvatarFileName = nil
        avatarUploadProgress = nil
    }

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