package com.yc.ship.module.marketing.controller.admin.couponpackagecode;

import cn.hutool.core.io.FastByteArrayOutputStream;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.URLUtil;
import com.yc.ship.framework.common.pojo.CommonResult;
import com.yc.ship.framework.common.pojo.PageParam;
import com.yc.ship.framework.common.pojo.PageResult;
import com.yc.ship.framework.common.util.object.BeanUtils;
import com.yc.ship.framework.excel.core.util.ExcelUtils;
import com.yc.ship.framework.operatelog.core.annotations.OperateLog;
import com.yc.ship.module.marketing.controller.admin.couponpackagecode.vo.CouponPackageCodePageReqVO;
import com.yc.ship.module.marketing.controller.admin.couponpackagecode.vo.CouponPackageCodeRespVO;
import com.yc.ship.module.marketing.controller.admin.couponpackagecode.vo.CouponPackageCodeSaveReqVO;
import com.yc.ship.module.marketing.dal.dataobject.coupon.CouponDO;
import com.yc.ship.module.marketing.dal.dataobject.couponpackage.CouponPackageDO;
import com.yc.ship.module.marketing.dal.dataobject.couponpackagecode.CouponPackageCodeDO;
import com.yc.ship.module.marketing.service.coupon.CouponService;
import com.yc.ship.module.marketing.service.couponpackage.CouponPackageService;
import com.yc.ship.module.marketing.service.couponpackagecode.CouponPackageCodeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.List;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static com.yc.ship.framework.common.pojo.CommonResult.success;
import static com.yc.ship.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;

@Tag(name = "管理后台 - 优惠券-券包领取码")
@RestController
@RequestMapping("/marketing/coupon-package-code")
@Validated
public class CouponPackageCodeController {

    @Resource
    private CouponPackageCodeService couponPackageCodeService;

    @Resource
    private CouponPackageService couponPackageService;

    @Resource
    private CouponService couponService;

    @Value("${yudao.host.out}")
    private String hostOut;

    @Value("${yudao.host.in}")
    private String hostIn;

    @PostMapping("/create")
    @Operation(summary = "创建优惠券-券包领取码")
    @PreAuthorize("@ss.hasPermission('marketing:coupon-package-code:create')")
    public CommonResult<Long> createCouponPackageCode(@Valid @RequestBody CouponPackageCodeSaveReqVO createReqVO) {
        return success(couponPackageCodeService.createCouponPackageCode(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新优惠券-券包领取码")
    @PreAuthorize("@ss.hasPermission('marketing:coupon-package-code:update')")
    public CommonResult<Boolean> updateCouponPackageCode(@Valid @RequestBody CouponPackageCodeSaveReqVO updateReqVO) {
        couponPackageCodeService.updateCouponPackageCode(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除优惠券-券包领取码")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('marketing:coupon-package-code:delete')")
    public CommonResult<Boolean> deleteCouponPackageCode(@RequestParam("id") Long id) {
        couponPackageCodeService.deleteCouponPackageCode(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得优惠券-券包领取码")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('marketing:coupon-package-code:query')")
    public CommonResult<CouponPackageCodeRespVO> getCouponPackageCode(@RequestParam("id") Long id) {
        CouponPackageCodeDO couponPackageCode = couponPackageCodeService.getCouponPackageCode(id);
        return success(BeanUtils.toBean(couponPackageCode, CouponPackageCodeRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得优惠券-券包领取码分页")
    @PreAuthorize("@ss.hasPermission('marketing:coupon-package-code:query')")
    public CommonResult<PageResult<CouponPackageCodeRespVO>> getCouponPackageCodePage(@Valid CouponPackageCodePageReqVO pageReqVO) {
        PageResult<CouponPackageCodeDO> pageResult = couponPackageCodeService.getCouponPackageCodePage(pageReqVO);
        PageResult<CouponPackageCodeRespVO> page = BeanUtils.toBean(pageResult, CouponPackageCodeRespVO.class);
        List<CouponPackageCodeRespVO> list = page.getList();
        Long packageId = pageReqVO.getPackageId();
        CouponPackageDO couponPackage = couponPackageService.getCouponPackage(packageId);
        if(couponPackage != null) {
            Long couponId = couponPackage.getCouponId();
            CouponDO coupon = couponService.getCoupon(couponId);
            list.stream().forEach(item -> {
                item.setPackageName(couponPackage.getPackageName());
                if(coupon != null) {
                    item.setCouponName(coupon.getName());
                }
            });
        }
        return success(page);
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出优惠券-券包领取码 Excel")
    @PreAuthorize("@ss.hasPermission('marketing:coupon-package-code:export')")
    @OperateLog(type = EXPORT,enable = false)
    public void exportCouponPackageCodeExcel(@Valid CouponPackageCodePageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<CouponPackageCodeDO> list = couponPackageCodeService.getCouponPackageCodePage(pageReqVO).getList();
        List<CouponPackageCodeRespVO> resultList = BeanUtils.toBean(list, CouponPackageCodeRespVO.class);
        Long packageId = pageReqVO.getPackageId();
        CouponPackageDO couponPackage = couponPackageService.getCouponPackage(packageId);
        if(couponPackage != null) {
            Long couponId = couponPackage.getCouponId();
            CouponDO coupon = couponService.getCoupon(couponId);
            resultList.stream().forEach(item -> {
                item.setPackageName(couponPackage.getPackageName());
                if(coupon != null) {
                    item.setCouponName(coupon.getName());
                }
            });
        }
        // 导出 Excel
        ExcelUtils.write(response, "优惠券-券包领取码.xls", "数据", CouponPackageCodeRespVO.class,
                resultList);
    }

    @GetMapping("/download-qrcode")
    @Operation(summary = "下载优惠券-券包领取码二维码")
    @PreAuthorize("@ss.hasPermission('marketing:coupon-package-code:download')")
    @OperateLog(type = EXPORT,enable = false)
    public void downloadQrCode(@RequestParam("packageId") Long packageId, HttpServletResponse response) throws IOException {
       List<CouponPackageCodeDO> list = couponPackageCodeService.getListByPackageId(packageId);
       List<String> urls = list.stream().map(item -> item.getQrCode()).collect(Collectors.toList());
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(outputStream);
           urls.stream().forEach(url -> {
               url = url.replaceAll(hostOut,hostIn);

               URL url3 = null;
               try {
                   url3 = new URL(url);

                   InputStream stream = URLUtil.getStream(url3);
                   FastByteArrayOutputStream read = IoUtil.read(stream);
                   byte[] bytes = read.toByteArray();
                   // 文件流添加到zip流
                   zip.putNextEntry(new ZipEntry(FileUtil.getName(url)));
                   zip.write(bytes);
                   IOUtils.closeQuietly(read);
                   zip.flush();
                   zip.closeEntry();
               } catch (MalformedURLException e) {
                   throw new RuntimeException(e);
               } catch (IOException e) {
                   throw new RuntimeException(e);
               }

           });
        IOUtils.closeQuietly(zip);
        byte[] bytes = outputStream.toByteArray();
        response.reset();
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("优惠券-券包领取码二维码.zip", "UTF-8"));
        response.setContentType("application/octet-stream; charset=UTF-8");
        response.addHeader("Content-Length", "" + bytes.length);
        IOUtils.write(bytes, response.getOutputStream());


    }

}