package com.gxwebsoft.shop.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gxwebsoft.common.core.config.ConfigProperties;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.system.entity.FileRecord;
import com.gxwebsoft.shop.entity.ShopGoods;
import com.gxwebsoft.shop.service.ShopGiftService;
import com.gxwebsoft.shop.entity.ShopGift;
import com.gxwebsoft.shop.param.ShopGiftParam;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.shop.service.ShopGoodsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 礼品卡控制器
 *
 * @author 科技小王子
 * @since 2025-08-11 18:07:32
 */
@Tag(name = "礼品卡管理")
@RestController
@RequestMapping("/api/shop/shop-gift")
public class ShopGiftController extends BaseController {
    @Resource
    private ShopGiftService shopGiftService;
    @Value("${config.upload-path}")
    private String uploadPath;
    @Value("${config.api-url}")
    private String apiUrl;
    @Resource
    private ShopGoodsService shopGoodsService;

    @Operation(summary = "根据code查询礼品卡")
    @GetMapping("/by-code/{code}")
    public ApiResult<ShopGift> get(@PathVariable("code") String code) {
        // 使用关联查询
        return success(shopGiftService.getByCode(code));
    }

    @Operation(summary = "礼品卡核销")
    @PostMapping("/set-take")
    public ApiResult<?> setTake(@RequestBody ShopGift shopGift) {
        if (getLoginUser() == null) return fail("请登录");
        if (shopGift.getCode() == null) {
            return fail("非法请求");
        }
        ShopGift shopGift1 = shopGiftService.getByCode(shopGift.getCode());
        if (shopGift1 == null) return fail("礼品卡不存在");
        if (shopGift1.getTakeTime() != null) {
            return fail("礼品卡已使用");
        }
        shopGift1.setTakeTime(LocalDateTime.now());
        shopGift1.setOperatorUserId(getLoginUserId());
        shopGiftService.updateById(shopGift1);
        return success();
    }

    @PreAuthorize("hasAuthority('shop:shopGift:list')")
    @Operation(summary = "分页查询礼品卡")
    @GetMapping("/page")
    public ApiResult<PageResult<ShopGift>> page(ShopGiftParam param) {
        // 使用关联查询
        return success(shopGiftService.pageRel(param));
    }

    @PreAuthorize("hasAuthority('shop:shopGift:list')")
    @Operation(summary = "查询全部礼品卡")
    @GetMapping()
    public ApiResult<List<ShopGift>> list(ShopGiftParam param) {
        // 使用关联查询
        return success(shopGiftService.listRel(param));
    }

    @PreAuthorize("hasAuthority('shop:shopGift:list')")
    @Operation(summary = "根据id查询礼品卡")
    @GetMapping("/{id}")
    public ApiResult<ShopGift> get(@PathVariable("id") Integer id) {
        // 使用关联查询
        return success(shopGiftService.getByIdRel(id));
    }

    @PreAuthorize("hasAuthority('shop:shopGift:save')")
    @OperationLog
    @Operation(summary = "添加礼品卡")
    @PostMapping()
    public ApiResult<?> save(@RequestBody ShopGift shopGift) {
        // 记录当前登录用户id
        User loginUser = getLoginUser();
        if (loginUser != null) {
            shopGift.setUserId(loginUser.getUserId());
        }
        if (shopGiftService.save(shopGift)) {
            return success("添加成功");
        }
        return fail("添加失败");
    }

    @PreAuthorize("hasAuthority('shop:shopGift:update')")
    @OperationLog
    @Operation(summary = "修改礼品卡")
    @PutMapping()
    public ApiResult<?> update(@RequestBody ShopGift shopGift) {
        if (shopGiftService.updateById(shopGift)) {
            return success("修改成功");
        }
        return fail("修改失败");
    }

    @PreAuthorize("hasAuthority('shop:shopGift:save')")
    @OperationLog
    @Operation(summary = "批量生成礼品卡")
    @PostMapping("/make")
    public ApiResult<?> make(@RequestBody ShopGift shopGiftData) {
        if (shopGiftData.getNum() == null || shopGiftData.getNum() <= 0) {
            return fail("请输入正确的数量");
        }
        if (shopGiftData.getGoodsId() == null || shopGiftData.getGoodsId() <= 0) {
            return fail("请选择商品");
        }
        List<ShopGift> giftList = new ArrayList<>();
        for (int i = 0; i < shopGiftData.getNum(); i++) {
            ShopGift shopGift = new ShopGift();
            shopGift.setName(shopGiftData.getName());
            shopGift.setCode(RandomUtil.randomString(8));
            shopGift.setGoodsId(shopGiftData.getGoodsId());
            shopGift.setUseLocation(shopGiftData.getUseLocation());
            shopGift.setComments(shopGiftData.getComments());
            giftList.add(shopGift);
        }
        if (shopGiftService.saveBatch(giftList)) {
            return success("生成成功");
        }
        return fail("生成失败");
    }

    @PreAuthorize("hasAuthority('shop:shopGift:remove')")
    @OperationLog
    @Operation(summary = "删除礼品卡")
    @DeleteMapping("/{id}")
    public ApiResult<?> remove(@PathVariable("id") Integer id) {
        if (shopGiftService.removeById(id)) {
            return success("删除成功");
        }
        return fail("删除失败");
    }

    @PreAuthorize("hasAuthority('shop:shopGift:save')")
    @OperationLog
    @Operation(summary = "批量添加礼品卡")
    @PostMapping("/batch")
    public ApiResult<?> saveBatch(@RequestBody List<ShopGift> list) {
        if (shopGiftService.saveBatch(list)) {
            return success("添加成功");
        }
        return fail("添加失败");
    }

    @PreAuthorize("hasAuthority('shop:shopGift:update')")
    @OperationLog
    @Operation(summary = "批量修改礼品卡")
    @PutMapping("/batch")
    public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopGift> batchParam) {
        if (batchParam.update(shopGiftService, "id")) {
            return success("修改成功");
        }
        return fail("修改失败");
    }

    @PreAuthorize("hasAuthority('shop:shopGift:remove')")
    @OperationLog
    @Operation(summary = "批量删除礼品卡")
    @DeleteMapping("/batch")
    public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
        if (shopGiftService.removeByIds(ids)) {
            return success("删除成功");
        }
        return fail("删除失败");
    }

    @PreAuthorize("hasAuthority('shop:shopGift:list')")
    @Operation(summary = "导出礼品卡")
    @PostMapping("/export")
    public ApiResult<?> export(@RequestBody(required = false) List<Integer> ids) throws IOException {
        String filename = "excel/礼品卡.xlsx";
        if (!FileUtil.exist(uploadPath + "excel")) {
            FileUtil.mkdir(uploadPath + "excel");
        }
        List<ShopGift> list;
        if (ids != null && !ids.isEmpty()) {
            list = shopGiftService.listByIds(ids);
        } else {
            list = shopGiftService.list();
        }
        if (!list.isEmpty()) {
            Set<Integer> goodsIds = list.stream().map(ShopGift::getGoodsId).collect(Collectors.toSet());
            List<ShopGoods> goodsList = shopGoodsService.listByIds(goodsIds);
            for (ShopGift shopGift : list) {
                ShopGoods shopGoods = goodsList.stream().filter(sG -> sG.getGoodsId().equals(shopGift.getGoodsId())).findFirst().orElse(null);
                if (shopGoods != null) {
                    shopGift.setGoods(shopGoods);
                }
            }
        }
        String path = uploadPath + filename;
        SXSSFWorkbook workbook = new SXSSFWorkbook();
        //创建工作表单
        SXSSFSheet sheet = workbook.createSheet();
        String[] headers = {"名称", "秘钥", "领取时间", "商品"};

        SXSSFRow row0 = sheet.createRow(0);
        for (int i = 0; i < headers.length; i++) {
            row0.createCell(i).setCellValue(headers[i]);
        }
        if (!list.isEmpty()) {
            for (ShopGift shopGift : list) {
                SXSSFRow row = sheet.createRow(sheet.getLastRowNum() + 1);
                row.createCell(0).setCellValue(shopGift.getName());
                row.createCell(1).setCellValue(shopGift.getCode());
                row.createCell(2).setCellValue(shopGift.getTakeTime());
                row.createCell(3).setCellValue(shopGift.getGoods() != null ? shopGift.getGoods().getName() : "");
            }
        }
        FileOutputStream output = new FileOutputStream(path);
        workbook.write(output);
        output.flush();

        FileRecord result = new FileRecord();
        result.setCreateUserId(getLoginUserId());
        result.setName("礼品卡");
        result.setPath(filename);
        result.setUrl(apiUrl + "/" + filename);
        return success(result);
    }

}
