package com.ruoyi.app.order;

import com.ruoyi.app.flashdelivery.dto.InfoAddressRequest;
import com.ruoyi.app.flashdelivery.service.InfoAddressBookService;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.InfoAddress;
import com.ruoyi.system.mapper.InfoAddressMapper;
import com.ruoyi.system.service.IInfoAddressService;
import com.ruoyi.system.utils.Auth;
import com.ruoyi.system.utils.JwtUtil;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;

/**
 * 地址簿接口。
 * App 端接口使用 token 绑定地址所有人；平台管理接口继续使用 Spring Security 权限。
 */
@RestController
@RequestMapping("/system/address")
public class InfoAddressController extends BaseController {
    @Autowired private IInfoAddressService infoAddressService;
    @Autowired private InfoAddressMapper infoAddressMapper;
    @Autowired private InfoAddressBookService addressBookService;

    /** 返回历史浏览器地图密钥；服务端 Routes 使用另一套不公开的密钥。 */
    @Anonymous
    @GetMapping("/getGoogleMapKey")
    public AjaxResult getGoogleMapKey() {
        List<SysDictData> data = DictUtils.getDictCache("sys_googlemap_key");
        return data != null && !data.isEmpty() ? success(data.get(0).getDictValue())
                : error(MessageUtils.message("no.map.exception"));
    }

    /** 查询当前用户拥有的地址详情。 */
    @Anonymous @Auth
    @GetMapping("/getaddressxq")
    public AjaxResult getaddressxq(@RequestHeader String token, @RequestParam Long id) {
        return success(MessageUtils.message("no.obtained.success"), addressBookService.detail(userId(token), id));
    }

    /** 查询当前用户地址簿中距离给定坐标最近的地址。 */
    @Anonymous @Auth
    @GetMapping("/getzuijinaddress")
    public AjaxResult getzuijinaddress(@RequestHeader String token, @RequestParam BigDecimal longitude,
                                       @RequestParam BigDecimal latitude) {
        return success(MessageUtils.message("no.obtained.success"),
                infoAddressMapper.getmyaddress(longitude, latitude, userId(token).intValue()));
    }

    /** 搜索当前用户地址簿，置顶地址优先。 */
    @Anonymous @Auth
    @GetMapping("/getaddress")
    public AjaxResult getaddress(@RequestHeader String token,
                                 @RequestParam(required = false) String keyword) {
        return success(MessageUtils.message("no.obtained.success"), addressBookService.list(userId(token), keyword));
    }

    /** 新增或修改当前用户地址，忽略客户端可能伪造的用户身份。 */
    @Anonymous @Auth
    @PostMapping("/address")
    public AjaxResult address(@RequestHeader String token, @RequestBody InfoAddressRequest request) {
        return success(addressBookService.save(userId(token), request));
    }

    /** 删除当前用户拥有的地址。 */
    @Anonymous @Auth
    @DeleteMapping(value = "/{id}", headers = "token")
    public AjaxResult deleteMine(@RequestHeader String token, @PathVariable Long id) {
        addressBookService.delete(userId(token), id);
        return success();
    }

    /** 将当前用户拥有的地址置顶。 */
    @Anonymous @Auth
    @PostMapping("/{id}/top")
    public AjaxResult top(@RequestHeader String token, @PathVariable Long id) {
        addressBookService.top(userId(token), id);
        return success();
    }

    @PreAuthorize("@ss.hasPermi('system:address:list')")
    @GetMapping("/list")
    public TableDataInfo list(InfoAddress infoAddress) {
        startPage();
        return getDataTable(infoAddressService.selectInfoAddressList(infoAddress));
    }

    @PreAuthorize("@ss.hasPermi('system:address:export')")
    @Log(title = "address", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, InfoAddress infoAddress) {
        new ExcelUtil<>(InfoAddress.class).exportExcel(response,
                infoAddressService.selectInfoAddressList(infoAddress), MessageUtils.message("no.export.excel.address"));
    }

    @PreAuthorize("@ss.hasPermi('system:address:query')")
    @GetMapping("/{id}")
    public AjaxResult getInfo(@PathVariable Long id) { return success(infoAddressService.selectInfoAddressById(id)); }

    @PreAuthorize("@ss.hasPermi('system:address:add')")
    @Log(title = "address", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody InfoAddress infoAddress) {
        return toAjax(infoAddressService.insertInfoAddress(infoAddress));
    }

    @PreAuthorize("@ss.hasPermi('system:address:edit')")
    @Log(title = "address", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody InfoAddress infoAddress) {
        return toAjax(infoAddressService.updateInfoAddress(infoAddress));
    }

    @PreAuthorize("@ss.hasPermi('system:address:remove')")
    @Log(title = "address", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(infoAddressService.deleteInfoAddressByIds(ids));
    }

    private Long userId(String token) { return Long.valueOf(new JwtUtil().getusid(token)); }
}
