//
//  WeChatShareService.swift
//  suixinkan
//

import UIKit
import WechatOpenSDK

/// 微信分享服务，封装文本、网页、图片和小程序分享能力，不包含微信支付。
enum WeChatShareService {
    /// 当前设备是否已安装微信且支持 Open SDK。
    static var isWeChatAvailable: Bool {
        WXApi.isWXAppInstalled() && WXApi.isWXAppSupport()
    }

    /// 分享纯文本到微信。
    @MainActor
    static func shareText(
        _ payload: WeChatTextSharePayload,
        scene: WeChatShareScene,
        completion: ((WeChatShareResult) -> Void)? = nil
    ) {
        let trimmed = payload.text.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !trimmed.isEmpty else {
            completion?(.invalidPayload("分享文本不能为空"))
            return
        }

        let request = SendMessageToWXReq()
        request.bText = true
        request.text = trimmed
        request.scene = scene.wxSceneValue
        WeChatManager.shared.sendShareRequest(request, completion: completion)
    }

    /// 分享网页链接到微信。
    @MainActor
    static func shareWebPage(
        _ payload: WeChatWebPageSharePayload,
        scene: WeChatShareScene,
        thumbImage: UIImage? = nil,
        completion: ((WeChatShareResult) -> Void)? = nil
    ) {
        let title = payload.title.trimmingCharacters(in: .whitespacesAndNewlines)
        let url = payload.url.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !title.isEmpty else {
            completion?(.invalidPayload("分享标题不能为空"))
            return
        }
        guard !url.isEmpty else {
            completion?(.invalidPayload("分享链接不能为空"))
            return
        }

        let webpageObject = WXWebpageObject()
        webpageObject.webpageUrl = url

        let message = WXMediaMessage()
        message.title = title
        message.description = payload.description
        message.mediaObject = webpageObject
        if let thumbImage, let thumbData = WeChatThumbImageProcessor.makeThumbData(from: thumbImage) {
            message.thumbData = thumbData
        }

        let request = SendMessageToWXReq()
        request.bText = false
        request.message = message
        request.scene = scene.wxSceneValue
        WeChatManager.shared.sendShareRequest(request, completion: completion)
    }

    /// 分享图片到微信。
    @MainActor
    static func shareImage(
        _ payload: WeChatImageSharePayload,
        scene: WeChatShareScene,
        thumbImage: UIImage? = nil,
        completion: ((WeChatShareResult) -> Void)? = nil
    ) {
        guard !payload.imageData.isEmpty else {
            completion?(.invalidPayload("分享图片不能为空"))
            return
        }

        let imageObject = WXImageObject()
        imageObject.imageData = payload.imageData

        let message = WXMediaMessage()
        message.mediaObject = imageObject
        if let thumbImage, let thumbData = WeChatThumbImageProcessor.makeThumbData(from: thumbImage) {
            message.thumbData = thumbData
        } else if let image = UIImage(data: payload.imageData),
                  let thumbData = WeChatThumbImageProcessor.makeThumbData(from: image) {
            message.thumbData = thumbData
        }

        let request = SendMessageToWXReq()
        request.bText = false
        request.message = message
        request.scene = scene.wxSceneValue
        WeChatManager.shared.sendShareRequest(request, completion: completion)
    }

    /// 分享小程序到微信好友会话。
    @MainActor
    static func shareMiniProgram(
        _ payload: WeChatMiniProgramSharePayload,
        previewImage: UIImage? = nil,
        completion: ((WeChatShareResult) -> Void)? = nil
    ) {
        switch makeMiniProgramRequest(payload, scene: .session, previewImage: previewImage ?? defaultThumbImage()) {
        case .success(let request):
            WeChatManager.shared.sendShareRequest(request, completion: completion)
        case .failure(let result):
            completion?(result)
        }
    }

    /// 构建小程序分享请求，供业务分享入口和单元测试复用。
    static func makeMiniProgramRequest(
        _ payload: WeChatMiniProgramSharePayload,
        scene: WeChatShareScene,
        previewImage: UIImage? = nil
    ) -> Result<SendMessageToWXReq, WeChatShareResult> {
        guard scene == .session else {
            return .failure(.invalidPayload("小程序仅支持分享到微信好友"))
        }

        let title = payload.title.trimmingCharacters(in: .whitespacesAndNewlines)
        let webpageURL = payload.webpageURL.trimmingCharacters(in: .whitespacesAndNewlines)
        let userName = payload.userName.trimmingCharacters(in: .whitespacesAndNewlines)
        let path = payload.path?.trimmingCharacters(in: .whitespacesAndNewlines)

        guard !title.isEmpty else {
            return .failure(.invalidPayload("分享标题不能为空"))
        }
        guard !webpageURL.isEmpty else {
            return .failure(.invalidPayload("小程序兼容网页链接不能为空"))
        }
        guard webpageURL.lengthOfBytes(using: .utf8) <= 1024 else {
            return .failure(.invalidPayload("小程序兼容网页链接不能超过1024字节"))
        }
        guard !userName.isEmpty else {
            return .failure(.invalidPayload("小程序原始 ID 不能为空"))
        }

        let miniProgramObject = WXMiniProgramObject()
        miniProgramObject.webpageUrl = webpageURL
        miniProgramObject.userName = userName
        miniProgramObject.path = path?.isEmpty == false ? path : nil
        miniProgramObject.miniProgramType = WXMiniProgramType(rawValue: UInt(payload.miniProgramType.resolvedForCurrentBuild.rawValue))
            ?? WXMiniProgramType(rawValue: UInt(WeChatMiniProgramType.release.rawValue))!
        miniProgramObject.withShareTicket = payload.withShareTicket
        miniProgramObject.disableForward = payload.disableForward
        if let previewImage {
            miniProgramObject.hdImageData = WeChatThumbImageProcessor.makeMiniProgramHDImageData(from: previewImage)
        }

        let message = WXMediaMessage()
        message.title = title
        message.description = payload.description
        message.mediaObject = miniProgramObject

        let request = SendMessageToWXReq()
        request.bText = false
        request.message = message
        request.scene = scene.wxSceneValue
        return .success(request)
    }

    /// 读取 App 图标，用作微信分享缩略图兜底。
    static func defaultThumbImage() -> UIImage? {
        guard let icons = Bundle.main.infoDictionary?["CFBundleIcons"] as? [String: Any],
              let primary = icons["CFBundlePrimaryIcon"] as? [String: Any],
              let iconFiles = primary["CFBundleIconFiles"] as? [String],
              let iconName = iconFiles.last else {
            return nil
        }
        return UIImage(named: iconName)
    }
}
