package org.dromara.mp.controller;

import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.material.WxMpMaterialFileBatchGetResult;
import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult;
import org.dromara.common.core.domain.R;
import org.dromara.common.web.core.BaseController;
import org.dromara.mp.annotation.SwitchoverCheck;
import org.dromara.mp.service.WxMpMaterialService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * 微信公众号素材管理控制器
 *
 * @author pengles
 */
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/wx/mp/media/{appid}")
public class WxMpMediaController extends BaseController {

    private final WxMpService wxMpService;
    private final WxMpMaterialService wxMpMaterialService;

    /**
     * 上传临时素材
     *
     * @param appid 公众号appid
     * @param type  素材类型（image、voice、video、thumb）
     * @param file  文件
     * @return 上传结果
     */
    @PostMapping("/upload/temp")
    @SwitchoverCheck
    public R<WxMediaUploadResult> uploadTempMedia(@PathVariable String appid,
                                                  @RequestParam String type,
                                                  @RequestParam("file") File file) {
        try {
            WxMediaUploadResult result = wxMpMaterialService.uploadTempMedia(type, file);
            return R.ok(result);
        } catch (Exception e) {
            log.error("上传临时素材失败: {}", e.getMessage(), e);
            return R.fail("上传临时素材失败: " + e.getMessage());
        }
    }

    /**
     * 下载临时素材
     *
     * @param appid    公众号appid
     * @param mediaId  素材ID
     * @param response HTTP响应
     */
    @GetMapping("/download/temp/{mediaId}")
    @SwitchoverCheck
    public void downloadTempMedia(@PathVariable String appid,
                                  @PathVariable String mediaId,
                                  HttpServletResponse response) {
        try {
            InputStream inputStream = wxMpMaterialService.downloadTempMedia(mediaId);
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=" + mediaId);

            try (OutputStream outputStream = response.getOutputStream()) {
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                outputStream.flush();
            }
        } catch (Exception e) {
            log.error("下载临时素材失败: {}", e.getMessage(), e);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 上传永久素材
     *
     * @param appid 公众号appid
     * @param type  素材类型（image、voice、video、thumb）
     * @param file  文件
     * @return 上传结果
     */
    @PostMapping("/upload/forever")
    @SwitchoverCheck
    public R<WxMpMaterialUploadResult> uploadForeverMedia(@PathVariable String appid,
                                                          @RequestParam String type,
                                                          @RequestParam("file") File file) {
        try {
            WxMpMaterialUploadResult result = wxMpMaterialService.uploadMaterial(type, file);
            return R.ok(result);
        } catch (Exception e) {
            log.error("上传永久素材失败: {}", e.getMessage(), e);
            return R.fail("上传永久素材失败: " + e.getMessage());
        }
    }

    /**
     * 删除永久素材
     *
     * @param appid   公众号appid
     * @param mediaId 素材ID
     * @return 删除结果
     */
    @DeleteMapping("/delete/forever/{mediaId}")
    @SwitchoverCheck
    public R<Void> deleteForeverMedia(@PathVariable String appid, @PathVariable String mediaId) {
        try {
            boolean result = wxMpMaterialService.deleteMaterial(mediaId);
            return result ? R.ok() : R.fail("删除永久素材失败");
        } catch (Exception e) {
            log.error("删除永久素材失败: {}", e.getMessage(), e);
            return R.fail("删除永久素材失败: " + e.getMessage());
        }
    }

    /**
     * 获取永久素材
     *
     * @param appid   公众号appid
     * @param mediaId 素材ID
     */
    @GetMapping("/get/forever/{mediaId}")
    @SwitchoverCheck
    public R<WxMpMaterialFileBatchGetResult.WxMaterialFileBatchGetNewsItem> getForeverMedia(@PathVariable String appid,
                                                                                            @PathVariable String mediaId) {
        WxMpMaterialFileBatchGetResult.WxMaterialFileBatchGetNewsItem wxMpMaterialServiceMaterial = wxMpMaterialService.getMaterial(mediaId);
        return R.ok(wxMpMaterialServiceMaterial);
    }

    /**
     * 获取素材总数
     *
     * @param appid 公众号appid
     * @return 素材总数
     */
    @GetMapping("/count")
    @SwitchoverCheck
    public R<Object> getMaterialCount(@PathVariable String appid) {
        try {
            Object count = wxMpMaterialService.getMaterialCount();
            return R.ok(count);
        } catch (Exception e) {
            log.error("获取素材总数失败: {}", e.getMessage(), e);
            return R.fail("获取素材总数失败: " + e.getMessage());
        }
    }

    /**
     * 获取素材列表
     *
     * @param appid  公众号appid
     * @param type   素材类型
     * @param offset 偏移量
     * @param count  数量
     * @return 素材列表
     */
    @GetMapping("/list")
    @SwitchoverCheck
    public R<Object> getMaterialList(@PathVariable String appid,
                                     @RequestParam String type,
                                     @RequestParam(defaultValue = "0") int offset,
                                     @RequestParam(defaultValue = "20") int count) {
        try {
            Object materialList = wxMpMaterialService.getMaterialList(type, offset, count);
            return R.ok(materialList);
        } catch (Exception e) {
            log.error("获取素材列表失败: {}", e.getMessage(), e);
            return R.fail("获取素材列表失败: " + e.getMessage());
        }
    }

    /**
     * 上传图文消息内的图片
     *
     * @param appid 公众号appid
     * @param file  图片文件
     * @return 上传结果
     */
    @PostMapping("/upload/img")
    @SwitchoverCheck
    public R<String> uploadImg(@PathVariable String appid,
                               @RequestParam("file") File file) {
        try {
            String url = wxMpMaterialService.uploadImg(file);
            return R.ok(url);
        } catch (Exception e) {
            log.error("上传图文消息图片失败: {}", e.getMessage(), e);
            return R.fail("上传图文消息图片失败: " + e.getMessage());
        }
    }
}
