package com.ruoyi.app.tableqrcode;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.system.domain.InfoUser;
import com.ruoyi.system.domain.PosOrder;
import com.ruoyi.system.domain.PosStore;
import com.ruoyi.system.domain.TableQrcode;
import com.ruoyi.system.service.IInfoUserService;
import com.ruoyi.system.service.IPosOrderService;
import com.ruoyi.system.service.IPosStoreService;
import com.ruoyi.system.service.ITableQrcodeService;
import com.ruoyi.system.utils.Auth;
import com.ruoyi.system.utils.JwtUtil;
import org.apache.catalina.Store;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 餐桌码管理Controller
 */
@RestController
@RequestMapping("/table-qrcode")
public class TableQrcodeController extends BaseController
{
    @Autowired
    private ITableQrcodeService tableQrcodeService;

    @Autowired
    private IInfoUserService infoUserService;

    @Autowired
    private IPosStoreService posStoreService;

    @Autowired
    private IPosOrderService posOrderService;


    /**
     * 创建餐桌码
     */
    @Anonymous
    @Auth
    @PostMapping("/add")
    @Transactional
    public AjaxResult add(@RequestHeader String token, @RequestBody TableQrcode tableQrcode)
    {
        // 参数校验
        if (tableQrcode.getTableNo() == null || tableQrcode.getTableNo().isEmpty())
        {
            return error("桌号不能为空");
        }
        if (tableQrcode.getType() == null || (tableQrcode.getType() != 0 && tableQrcode.getType() != 1))
        {
            return error("类型只能为0(摊位码)或1(公用码)");
        }

        // 获取当前用户
        JwtUtil jwtUtil = new JwtUtil();
        String userId = jwtUtil.getusid(token);
        InfoUser currentUser = infoUserService.selectInfoUserByUserId(Long.valueOf(userId));
        if (currentUser == null)
        {
            return error("用户不存在");
        }

        String userType = currentUser.getUserType();

        // 权限与参数处理
        if ("4".equals(userType) || "1".equals(userType))
        {
            // 摊主只能创建摊位码
            if (tableQrcode.getType() != 0)
            {
                return error("摊主只能创建摊位码");
            }
            // storeId 从用户信息获取
            if ("4".equals(userType) && currentUser.getStoreId() == null)
            {
                return error("当前用户未关联摊位");
            }
            PosStore store=posStoreService.getOne(new LambdaQueryWrapper<PosStore>().eq(PosStore::getId,tableQrcode.getStoreId()));
            if("4".equals(userType)) {
                tableQrcode.setStoreId(currentUser.getStoreId());

                // nightMarketId 从摊位信息获取
                 store = posStoreService.selectPosStoreById(currentUser.getStoreId());
            }
            if (store == null)
            {
                return error("店铺/摊位不存在");
            }
            tableQrcode.setNightMarketId(store.getNightMarketId());
        }
        else if ("3".equals(userType))
        {
            // 夜市管理员
            if (tableQrcode.getType() == 0)
            {
                // 创建摊位码，需指定 storeId
                if (tableQrcode.getStoreId() == null)
                {

                    return error("创建摊位码时请指定摊位");
                }
                PosStore store = posStoreService.selectPosStoreById(tableQrcode.getStoreId());
                if (store == null)
                {
                    return error("摊位不存在");
                }
                // 优先从摊位取 nightMarketId，若为空则从用户其他店铺获取
                if (store.getNightMarketId() != null)
                {
                    tableQrcode.setNightMarketId(store.getNightMarketId());
                }
                else
                {
                    List<PosStore> userStores = posStoreService.lambdaQuery()
                            .eq(PosStore::getUserId, Long.valueOf(userId))
                            .isNotNull(PosStore::getNightMarketId)
                            .last("limit 1").list();
                    if (!userStores.isEmpty())
                    {
                        tableQrcode.setNightMarketId(userStores.get(0).getNightMarketId());
                    }
                }
                if (tableQrcode.getNightMarketId() == null)
                {
                    return error("无法确定夜市ID，请先为店铺设置夜市关联");
                }
            }
            else
            {
                // 创建公用码，storeId 为空
                tableQrcode.setStoreId(null);
                // nightMarketId 需从当前用户关联的夜市获取
                // 夜市用户的 userId 对应 night_market 表的 user_id
                // 这里简化处理：通过用户关联的店铺获取 nightMarketId
                // 或者直接让前端传入
                if (tableQrcode.getNightMarketId() == null)
                {
                    // 尝试从用户关联的店铺获取
                    List<PosStore> stores = posStoreService.lambdaQuery()
                            .eq(PosStore::getUserId, Long.valueOf(userId))
                            .last("limit 1").list();
                    if (stores.isEmpty())
                    {
                        return error("请指定夜市ID");
                    }
                    tableQrcode.setNightMarketId(stores.get(0).getNightMarketId());
                }
            }
        }
        else
        {
            return error("无权创建餐桌码");
        }

        // 检查桌号是否重复
        int count = tableQrcodeService.checkTableNoUnique(tableQrcode);
        if (count > 0)
        {
            return error("桌号已存在");
        }

        // 生成二维码内容（insert 后生成）
        tableQrcode.setQrCode(null);
        tableQrcode.setStatus(0);
        tableQrcode.setUseStatus(0);
        tableQrcode.setCreateTime(new Date());
        tableQrcode.setCreateBy(userId);

        tableQrcodeService.insertTableQrcode(tableQrcode);

        // insert 后 id 已生成，更新二维码内容
        String qrCodeUrl = buildQrcodeUrl(tableQrcode);
        TableQrcode updateQr = new TableQrcode();
        updateQr.setId(tableQrcode.getId());
        updateQr.setQrCode(qrCodeUrl);
        tableQrcodeService.updateTableQrcode(updateQr);
        tableQrcode.setQrCode(qrCodeUrl);

        return success("创建成功", tableQrcode);
    }

    /**
     * 获取餐桌码列表
     */
    @Anonymous
    @Auth
    @GetMapping("/list")
    public AjaxResult list(@RequestHeader String token,
                           @RequestParam(required = false) Long storeId,
                           @RequestParam(required = false) Integer type,
                           @RequestParam(required = false) Integer status,
                           @RequestParam(required = false) Integer useStatus)
    {
        JwtUtil jwtUtil = new JwtUtil();
        String userId = jwtUtil.getusid(token);
        InfoUser currentUser = infoUserService.selectInfoUserByUserId(Long.valueOf(userId));

        LambdaQueryWrapper<TableQrcode> query = new LambdaQueryWrapper<>();
        query.eq(type!=null,TableQrcode::getType,type);
        query.eq(status!=null,TableQrcode::getStatus,status);
        query.eq(useStatus!=null,TableQrcode::getUseStatus,useStatus);

        if ("4".equals(currentUser.getUserType()))
        {
            // 摊主只能看自己的
            query.eq(TableQrcode::getStoreId,currentUser.getStoreId());
        }
        else if ("3".equals(currentUser.getUserType()))
        {
            query.eq(TableQrcode::getNightMarketId,Long.valueOf(userId));
            // 夜市管理员可按摊位筛选，或查看全部
            if (storeId != null)
            {
                query.eq(TableQrcode::getStoreId,storeId);
            }
        }
        else if("1".equals(currentUser.getUserType())){
            List<PosStore> stores=posStoreService.list(new LambdaQueryWrapper<PosStore>().eq(PosStore::getUserId,userId));
            if(stores.isEmpty()){
                query.eq(TableQrcode::getId,0L);
            }else{
                query.in(TableQrcode::getStoreId,stores.stream().map(PosStore::getId).collect(Collectors.toList()));
            }

        }
        List<TableQrcode> list = tableQrcodeService.list(query);
        Set<Long> storeIds = list.stream()
                .map(TableQrcode::getStoreId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        if (!storeIds.isEmpty())
        {
            Map<Long, String> storeNames = posStoreService.listByIds(storeIds).stream()
                    .filter(store -> store.getId() != null)
                    .collect(Collectors.toMap(
                            store -> store.getId().longValue(),
                            PosStore::getPosName,
                            (first, second) -> first));
            list.forEach(tableQrcode -> tableQrcode.setStoreName(
                    tableQrcode.getStoreId() == null ? null : storeNames.get(tableQrcode.getStoreId())));
        }
        return success(list);
    }

    /**
     * 获取餐桌码详情
     */
    @Anonymous
    @Auth
    @GetMapping("/{id}")
    public AjaxResult getInfo(@RequestHeader String token, @PathVariable Long id)
    {
//        if (!verifyOwnership(token, id))
//        {
//            return error("无权访问");
//        }
        TableQrcode tableQrcode = tableQrcodeService.selectTableQrcodeById(id);
        if (tableQrcode == null)
        {
            return error("餐桌码不存在");
        }
        return success(tableQrcode);
    }

    /**
     * 更新餐桌码
     */
    @Anonymous
    @Auth
    @PutMapping("/update")
    @Transactional
    public AjaxResult update(@RequestHeader String token, @RequestBody TableQrcode tableQrcode)
    {
        if (tableQrcode.getId() == null)
        {
            return error("ID不能为空");
        }
        if (!verifyOwnership(token, tableQrcode.getId()))
        {
            return error("无权操作");
        }

        // 只允许更新桌号和备注，不允许修改 type 和 storeId
        TableQrcode existing = tableQrcodeService.selectTableQrcodeById(tableQrcode.getId());
        if (existing == null)
        {
            return error("餐桌码不存在");
        }

        // 检查桌号重复
        if (tableQrcode.getTableNo() != null && !tableQrcode.getTableNo().equals(existing.getTableNo()))
        {
            TableQrcode check = new TableQrcode();
            check.setTableNo(tableQrcode.getTableNo());
            check.setType(existing.getType());
            check.setStoreId(existing.getStoreId());
            check.setNightMarketId(existing.getNightMarketId());
            check.setId(existing.getId());
            if (tableQrcodeService.checkTableNoUnique(check) > 0)
            {
                return error("桌号已存在");
            }
        }

        // 构建更新对象
        TableQrcode updateObj = new TableQrcode();
        updateObj.setId(existing.getId());
        updateObj.setTableNo(tableQrcode.getTableNo());
        updateObj.setRemark(tableQrcode.getRemark());
        updateObj.setUpdateTime(new Date());

        JwtUtil jwtUtil = new JwtUtil();
        updateObj.setUpdateBy(jwtUtil.getusid(token));

        // 如果桌号变更，需要更新二维码内容
        if (tableQrcode.getTableNo() != null && !tableQrcode.getTableNo().equals(existing.getTableNo()))
        {
            existing.setTableNo(tableQrcode.getTableNo());
            updateObj.setQrCode(buildQrcodeUrl(existing));
        }

        tableQrcodeService.updateTableQrcode(updateObj);
        return success("更新成功");
    }

    /**
     * 删除餐桌码
     */
    @Anonymous
    @Auth
    @DeleteMapping("/delete/{id}")
    @Transactional
    public AjaxResult delete(@RequestHeader String token, @PathVariable Long id)
    {
        if (!verifyOwnership(token, id))
        {
            return error("无权操作");
        }
        TableQrcode existing = tableQrcodeService.selectTableQrcodeById(id);
        if (existing == null)
        {
            return error("餐桌码不存在");
        }
        if (existing.getUseStatus() != null && existing.getUseStatus() == 1)
        {
            return error("使用中的餐桌码不能删除");
        }
        tableQrcodeService.deleteTableQrcodeById(id);
        return success("删除成功");
    }

    /**
     * 切换启用/停用状态
     */
    @Anonymous
    @Auth
    @PutMapping("/changeStatus")
    @Transactional
    public AjaxResult changeStatus(@RequestHeader String token, @RequestBody TableQrcode req)
    {
        if (req.getId() == null || req.getStatus() == null)
        {
            return error("参数不完整");
        }
        if (!verifyOwnership(token, req.getId()))
        {
            return error("无权操作");
        }

        TableQrcode updateObj = new TableQrcode();
        updateObj.setId(req.getId());
        updateObj.setStatus(req.getStatus());
        updateObj.setUpdateTime(new Date());
        JwtUtil jwtUtil = new JwtUtil();
        updateObj.setUpdateBy(jwtUtil.getusid(token));

        tableQrcodeService.updateTableQrcode(updateObj);
        return success("操作成功");
    }

    /**
     * 查看餐桌关联订单
     */
    @Anonymous
    @Auth
    @GetMapping("/getTableOrders")
    public AjaxResult getTableOrders(@RequestHeader String token,
                                      @RequestParam Long id,
                                      @RequestParam(defaultValue = "1") Integer page,
                                      @RequestParam(defaultValue = "10") Integer size,
                                      @RequestParam(required = false) String state)
    {
        if (!verifyOwnership(token, id))
        {
            return error("无权访问");
        }

        IPage<PosOrder> pageParam = new Page<>(page, size);
        QueryWrapper<PosOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("table_id", id).orderByDesc("cretim");
        if (state != null && !state.isEmpty())
        {
            if (state.equals("z01"))
            {
                queryWrapper.apply("((state = 0 AND (collect_payment = 1 OR type = 1)) OR (state = 1))");
            }
            else if (state.equals("z234"))
            {
                queryWrapper.in("state", 2, 3, 4);
            }
            else if (state.equals("z23"))
            {
                queryWrapper.in("state", 2, 3);
            }
            else if (state.equals("z34"))
            {
                queryWrapper.in("state", 3, 4);
            }
            else if (state.equals("z678911"))
            {
                queryWrapper.in("state", 6, 7, 8, 9, 11);
            }
            else
            {
                queryWrapper.eq("state", state);
            }
        }

        IPage<PosOrder> result = posOrderService.page(pageParam, queryWrapper);
        return success(result);
    }

    /**
     * 获取二维码图片
     */
    @Anonymous
    @Auth
    @GetMapping("/qrcode/{id}")
    public AjaxResult getQrcodeImage(@RequestHeader String token, @PathVariable Long id)
    {
        if (!verifyOwnership(token, id))
        {
            return error("无权访问");
        }
        TableQrcode tableQrcode = tableQrcodeService.selectTableQrcodeById(id);
        if (tableQrcode == null)
        {
            return error("餐桌码不存在");
        }

        // 如果还没有二维码内容，先生成
        if (tableQrcode.getQrCode() == null || tableQrcode.getQrCode().isEmpty())
        {
            String qrCodeUrl = buildQrcodeUrl(tableQrcode);
            TableQrcode updateObj = new TableQrcode();
            updateObj.setId(id);
            updateObj.setQrCode(qrCodeUrl);
            tableQrcodeService.updateTableQrcode(updateObj);
            tableQrcode.setQrCode(qrCodeUrl);
        }

        String base64Image = tableQrcodeService.generateQrcodeImage(id);
        if (base64Image == null)
        {
            return error("二维码生成失败");
        }
        return success("操作成功", base64Image);
    }

    /**
     * 扫码入口（C端）
     */
    @Anonymous
    @GetMapping("/scan")
    public String scan(@RequestParam Long tableId)
    {
        TableQrcode tableQrcode = tableQrcodeService.selectTableQrcodeById(tableId);
        if (tableQrcode == null)
        {
            return "redirect:/error?msg=餐桌码不存在";
        }
        if (tableQrcode.getStatus() != null && tableQrcode.getStatus() == 1)
        {
            return "redirect:/error?msg=该餐桌码已停用";
        }

        // 更新使用状态为使用中
        TableQrcode updateObj = new TableQrcode();
        updateObj.setId(tableId);
        updateObj.setUseStatus(1);
        tableQrcodeService.updateTableQrcode(updateObj);

        // 根据 type 跳转
        if (tableQrcode.getType() == 0)
        {
            // 摊位码 → 摊位商品页
            return "redirect:/store/products?storeId=" + tableQrcode.getStoreId() + "&tableId=" + tableId;
        }
        else
        {
            // 公用码 → 摊位选择页
            return "redirect:/market/stores?nightMarketId=" + tableQrcode.getNightMarketId() + "&tableId=" + tableId;
        }
    }

    /**
     * 构建二维码URL
     * 摊位码(type=0): id=摊位storeId
     * 公用码(type=1): id=夜市nightMarketId
     */
    private String buildQrcodeUrl(TableQrcode tableQrcode)
    {
        String id;
        if (tableQrcode.getType() == 0)
        {
            id = String.valueOf(tableQrcode.getStoreId());
        }
        else
        {
            id = String.valueOf(tableQrcode.getNightMarketId());
        }
        return "chachaeatapp://scan?id=" + id + "&type=" + tableQrcode.getType() + "&tableId=" + tableQrcode.getId() + "&tableNo=" + tableQrcode.getTableNo();
    }

    /**
     * 验证当前用户是否有权操作指定餐桌码
     */
    private boolean verifyOwnership(String token, Long tableId)
    {
        JwtUtil jwtUtil = new JwtUtil();
        String userId = jwtUtil.getusid(token);
        InfoUser currentUser = infoUserService.selectInfoUserByUserId(Long.valueOf(userId));

        TableQrcode tableQrcode = tableQrcodeService.selectTableQrcodeById(tableId);
        if (tableQrcode == null)
        {
            return false;
        }
        if("1".equals(currentUser.getUserType())){
            if (tableQrcode.getStoreId() == null)
            {
                return false;
            }
            List<PosStore> stores=posStoreService.list(new LambdaQueryWrapper<PosStore>().eq(PosStore::getUserId,currentUser.getUserId()));
            return stores.stream().anyMatch(x -> x.getId().equals(tableQrcode.getStoreId().intValue()));
        }

        if ("4".equals(currentUser.getUserType()))
        {
            // 摊主只能操作自己的
            return tableQrcode.getStoreId() != null && tableQrcode.getStoreId().equals(currentUser.getStoreId());
        }

        else if ("3".equals(currentUser.getUserType()))
        {
            // 夜市管理员可以操作自己夜市下的所有码
            // 通过 userId 查找管理的夜市
            List<PosStore> stores = posStoreService.lambdaQuery()
                    .eq(PosStore::getUserId, Long.valueOf(userId))
                    .last("limit 1").list();
            if (!stores.isEmpty())
            {
                Long nightMarketId = stores.get(0).getNightMarketId();
                return nightMarketId != null && nightMarketId.equals(tableQrcode.getNightMarketId());
            }
            return false;
        }
        return false;
    }
}
