package com.ruoyi.payment.controller;

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

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

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.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.payment.domain.EscrowAccount;
import com.ruoyi.payment.service.IEscrowAccountService;

/**
 * 资金监管账户API控制器
 * 
 * 提供监管账户创建、资金分配、转账等RESTful API接口
 * 
 * @author ruoyi
 * @date 2025-12-19
 */
@RestController
@RequestMapping("/api/payment/escrow")
public class EscrowAccountController extends BaseController
{
    @Autowired
    private IEscrowAccountService escrowAccountService;

    /**
     * 创建监管账户
     * 
     * @param applicationId 融资申请ID
     * @param totalAmount 总金额
     * @return 创建结果
     */
    @PreAuthorize("@ss.hasPermi('payment:escrow:add')")
    @Log(title = "资金监管账户", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult createEscrowAccount(
            @RequestParam("applicationId") Long applicationId,
            @RequestParam("totalAmount") BigDecimal totalAmount)
    {
        try {
            EscrowAccount account = escrowAccountService.createEscrowAccount(applicationId, totalAmount);
            return AjaxResult.success("监管账户创建成功", account);
        } catch (Exception e) {
            logger.error("创建监管账户失败", e);
            return error("创建监管账户失败: " + e.getMessage());
        }
    }

    /**
     * 资金存入
     * 
     * @param accountId 账户ID
     * @param amount 存入金额
     * @return 存入结果
     */
    @PreAuthorize("@ss.hasPermi('payment:escrow:edit')")
    @Log(title = "资金监管账户", businessType = BusinessType.UPDATE)
    @PutMapping("/{accountId}/deposit")
    public AjaxResult depositFunds(@PathVariable("accountId") Long accountId, 
                                 @RequestParam("amount") BigDecimal amount)
    {
        try {
            boolean result = escrowAccountService.depositFunds(accountId, amount);
            return toAjax(result);
        } catch (Exception e) {
            logger.error("资金存入失败", e);
            return error("资金存入失败: " + e.getMessage());
        }
    }

    /**
     * 资金分配
     * 
     * @param accountId 账户ID
     * @param distributionPlan 分配计划
     * @return 分配结果
     */
    @PreAuthorize("@ss.hasPermi('payment:escrow:edit')")
    @Log(title = "资金监管账户", businessType = BusinessType.UPDATE)
    @PutMapping("/{accountId}/distribute")
    public AjaxResult distributeFunds(@PathVariable("accountId") Long accountId, 
                                    @RequestBody Map<String, BigDecimal> distributionPlan)
    {
        try {
            boolean result = escrowAccountService.distributeFunds(accountId, distributionPlan);
            return toAjax(result);
        } catch (Exception e) {
            logger.error("资金分配失败", e);
            return error("资金分配失败: " + e.getMessage());
        }
    }

    /**
     * 资金转账
     * 
     * @param fromAccountId 转出账户ID
     * @param toAccountId 转入账户ID
     * @param amount 转账金额
     * @return 转账结果
     */
    @PreAuthorize("@ss.hasPermi('payment:escrow:edit')")
    @Log(title = "资金监管账户", businessType = BusinessType.UPDATE)
    @PostMapping("/transfer")
    public AjaxResult transferFunds(
            @RequestParam("fromAccountId") Long fromAccountId,
            @RequestParam("toAccountId") Long toAccountId,
            @RequestParam("amount") BigDecimal amount)
    {
        try {
            boolean result = escrowAccountService.transferFunds(fromAccountId, toAccountId, amount);
            return toAjax(result);
        } catch (Exception e) {
            logger.error("资金转账失败", e);
            return error("资金转账失败: " + e.getMessage());
        }
    }

    /**
     * 冻结资金
     * 
     * @param accountId 账户ID
     * @param amount 冻结金额
     * @return 冻结结果
     */
    @PreAuthorize("@ss.hasPermi('payment:escrow:edit')")
    @Log(title = "资金监管账户", businessType = BusinessType.UPDATE)
    @PutMapping("/{accountId}/freeze")
    public AjaxResult freezeFunds(@PathVariable("accountId") Long accountId, 
                                @RequestParam("amount") BigDecimal amount)
    {
        try {
            boolean result = escrowAccountService.freezeFunds(accountId, amount);
            return toAjax(result);
        } catch (Exception e) {
            logger.error("冻结资金失败", e);
            return error("冻结资金失败: " + e.getMessage());
        }
    }

    /**
     * 解冻资金
     * 
     * @param accountId 账户ID
     * @param amount 解冻金额
     * @return 解冻结果
     */
    @PreAuthorize("@ss.hasPermi('payment:escrow:edit')")
    @Log(title = "资金监管账户", businessType = BusinessType.UPDATE)
    @PutMapping("/{accountId}/unfreeze")
    public AjaxResult unfreezeFunds(@PathVariable("accountId") Long accountId, 
                                  @RequestParam("amount") BigDecimal amount)
    {
        try {
            boolean result = escrowAccountService.unfreezeFunds(accountId, amount);
            return toAjax(result);
        } catch (Exception e) {
            logger.error("解冻资金失败", e);
            return error("解冻资金失败: " + e.getMessage());
        }
    }

    /**
     * 查询账户余额
     * 
     * @param accountId 账户ID
     * @return 账户余额信息
     */
    @PreAuthorize("@ss.hasPermi('payment:escrow:query')")
    @GetMapping("/{accountId}/balance")
    public AjaxResult getAccountBalance(@PathVariable("accountId") Long accountId)
    {
        try {
            Map<String, BigDecimal> balance = escrowAccountService.getAccountBalance(accountId);
            return AjaxResult.success("账户余额", balance);
        } catch (Exception e) {
            logger.error("查询账户余额失败", e);
            return error("查询账户余额失败: " + e.getMessage());
        }
    }

    /**
     * 监控账户状态
     * 
     * @param accountId 账户ID
     * @return 账户状态信息
     */
    @PreAuthorize("@ss.hasPermi('payment:escrow:query')")
    @GetMapping("/{accountId}/status")
    public AjaxResult monitorAccountStatus(@PathVariable("accountId") Long accountId)
    {
        try {
            Map<String, Object> status = escrowAccountService.monitorAccountStatus(accountId);
            return AjaxResult.success("账户状态", status);
        } catch (Exception e) {
            logger.error("监控账户状态失败", e);
            return error("监控账户状态失败: " + e.getMessage());
        }
    }

    /**
     * 跟踪资金流向
     * 
     * @param accountId 账户ID
     * @return 资金流向记录
     */
    @PreAuthorize("@ss.hasPermi('payment:escrow:query')")
    @GetMapping("/{accountId}/flow")
    public AjaxResult trackFundFlow(@PathVariable("accountId") Long accountId)
    {
        try {
            List<Map<String, Object>> flow = escrowAccountService.trackFundFlow(accountId);
            return AjaxResult.success("资金流向", flow);
        } catch (Exception e) {
            logger.error("跟踪资金流向失败", e);
            return error("跟踪资金流向失败: " + e.getMessage());
        }
    }

    /**
     * 获取监管账户详情
     * 
     * @param accountId 账户ID
     * @return 账户详情
     */
    @PreAuthorize("@ss.hasPermi('payment:escrow:query')")
    @GetMapping("/{accountId}")
    public AjaxResult getEscrowAccount(@PathVariable("accountId") Long accountId)
    {
        try {
            EscrowAccount account = escrowAccountService.selectEscrowAccountById(accountId);
            if (account != null) {
                return success(account);
            } else {
                return error("监管账户不存在");
            }
        } catch (Exception e) {
            logger.error("查询监管账户失败", e);
            return error("查询监管账户失败: " + e.getMessage());
        }
    }

    /**
     * 根据申请ID查询监管账户
     * 
     * @param applicationId 申请ID
     * @return 监管账户
     */
    @PreAuthorize("@ss.hasPermi('payment:escrow:query')")
    @GetMapping("/application/{applicationId}")
    public AjaxResult getEscrowAccountByApplicationId(@PathVariable("applicationId") Long applicationId)
    {
        try {
            EscrowAccount account = escrowAccountService.selectEscrowAccountByApplicationId(applicationId);
            if (account != null) {
                return success(account);
            } else {
                return error("该申请暂无监管账户");
            }
        } catch (Exception e) {
            logger.error("根据申请ID查询监管账户失败", e);
            return error("查询失败: " + e.getMessage());
        }
    }

    /**
     * 查询监管账户列表
     * 
     * @param escrowAccount 查询条件
     * @return 账户列表
     */
    @PreAuthorize("@ss.hasPermi('payment:escrow:list')")
    @GetMapping
    public TableDataInfo getEscrowAccountList(EscrowAccount escrowAccount)
    {
        try {
            startPage();
            List<EscrowAccount> list = escrowAccountService.selectEscrowAccountList(escrowAccount);
            return getDataTable(list);
        } catch (Exception e) {
            logger.error("查询监管账户列表失败", e);
            return getDataTable(null);
        }
    }

    /**
     * 更新账户状态
     * 
     * @param accountId 账户ID
     * @param status 状态
     * @return 更新结果
     */
    @PreAuthorize("@ss.hasPermi('payment:escrow:edit')")
    @Log(title = "资金监管账户", businessType = BusinessType.UPDATE)
    @PutMapping("/{accountId}/status")
    public AjaxResult updateAccountStatus(@PathVariable("accountId") Long accountId, 
                                        @RequestParam("status") String status)
    {
        try {
            boolean result = escrowAccountService.updateAccountStatus(accountId, status);
            return toAjax(result);
        } catch (Exception e) {
            logger.error("更新账户状态失败", e);
            return error("更新账户状态失败: " + e.getMessage());
        }
    }

    /**
     * 验证账户余额充足
     * 
     * @param accountId 账户ID
     * @param amount 金额
     * @return 验证结果
     */
    @PreAuthorize("@ss.hasPermi('payment:escrow:query')")
    @GetMapping("/{accountId}/validate-balance")
    public AjaxResult validateSufficientBalance(@PathVariable("accountId") Long accountId, 
                                              @RequestParam("amount") BigDecimal amount)
    {
        try {
            boolean sufficient = escrowAccountService.validateSufficientBalance(accountId, amount);
            return AjaxResult.success("余额验证", sufficient);
        } catch (Exception e) {
            logger.error("验证账户余额失败", e);
            return error("验证账户余额失败: " + e.getMessage());
        }
    }

    /**
     * 导出监管账户数据
     * 
     * @param response HTTP响应
     * @param escrowAccount 查询条件
     */
    @PreAuthorize("@ss.hasPermi('payment:escrow:export')")
    @Log(title = "资金监管账户", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, EscrowAccount escrowAccount)
    {
        try {
            List<EscrowAccount> list = escrowAccountService.selectEscrowAccountList(escrowAccount);
            ExcelUtil<EscrowAccount> util = new ExcelUtil<EscrowAccount>(EscrowAccount.class);
            util.exportExcel(response, list, "资金监管账户数据");
        } catch (Exception e) {
            logger.error("导出监管账户数据失败", e);
        }
    }
}