package com.ruoyi.analytics.controller;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

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.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.analytics.service.IDataQueryService;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;

/**
 * 数据查询和展示API控制器
 * 
 * 提供债权状态查询、历史记录查看、实时数据更新等RESTful API接口
 * 
 * @author ruoyi
 * @date 2025-12-19
 */
@RestController
@RequestMapping("/api/data")
public class DataQueryController extends BaseController
{
    @Autowired
    private IDataQueryService dataQueryService;

    /**
     * 查询债权状态
     * 
     * @param creditId 债权ID
     * @return 债权状态信息
     */
    @PreAuthorize("@ss.hasPermi('data:credit:query')")
    @GetMapping("/credits/{creditId}/status")
    public AjaxResult queryCreditStatus(@PathVariable("creditId") Long creditId)
    {
        try {
            Map<String, Object> creditStatus = dataQueryService.queryCreditStatus(creditId);
            return AjaxResult.success("查询成功", creditStatus);
        } catch (Exception e) {
            logger.error("查询债权状态失败", e);
            return error("查询债权状态失败: " + e.getMessage());
        }
    }

    /**
     * 批量查询债权状态
     * 
     * @param creditIds 债权ID列表
     * @return 债权状态信息列表
     */
    @PreAuthorize("@ss.hasPermi('data:credit:query')")
    @PostMapping("/credits/batch-status")
    public AjaxResult batchQueryCreditStatus(@RequestBody List<Long> creditIds)
    {
        try {
            List<Map<String, Object>> creditStatuses = dataQueryService.batchQueryCreditStatus(creditIds);
            return AjaxResult.success("批量查询成功", creditStatuses);
        } catch (Exception e) {
            logger.error("批量查询债权状态失败", e);
            return error("批量查询债权状态失败: " + e.getMessage());
        }
    }

    /**
     * 查询债权历史记录
     * 
     * @param creditId 债权ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 历史记录列表
     */
    @PreAuthorize("@ss.hasPermi('data:credit:query')")
    @GetMapping("/credits/{creditId}/history")
    public AjaxResult queryCreditHistory(
            @PathVariable("creditId") Long creditId,
            @RequestParam(value = "startDate", required = false) String startDate,
            @RequestParam(value = "endDate", required = false) String endDate)
    {
        try {
            Date start = parseDate(startDate);
            Date end = parseDate(endDate);
            
            List<Map<String, Object>> history = dataQueryService.queryCreditHistory(creditId, start, end);
            return AjaxResult.success("查询历史记录成功", history);
        } catch (Exception e) {
            logger.error("查询债权历史记录失败", e);
            return error("查询债权历史记录失败: " + e.getMessage());
        }
    }

    /**
     * 查询合同状态
     * 
     * @param contractId 合同ID
     * @return 合同状态信息
     */
    @PreAuthorize("@ss.hasPermi('data:contract:query')")
    @GetMapping("/contracts/{contractId}/status")
    public AjaxResult queryContractStatus(@PathVariable("contractId") Long contractId)
    {
        try {
            Map<String, Object> contractStatus = dataQueryService.queryContractStatus(contractId);
            return AjaxResult.success("查询成功", contractStatus);
        } catch (Exception e) {
            logger.error("查询合同状态失败", e);
            return error("查询合同状态失败: " + e.getMessage());
        }
    }

    /**
     * 查询融资申请状态
     * 
     * @param applicationId 申请ID
     * @return 融资申请状态信息
     */
    @PreAuthorize("@ss.hasPermi('data:financing:query')")
    @GetMapping("/financing/{applicationId}/status")
    public AjaxResult queryFinancingApplicationStatus(@PathVariable("applicationId") Long applicationId)
    {
        try {
            Map<String, Object> applicationStatus = dataQueryService.queryFinancingApplicationStatus(applicationId);
            return AjaxResult.success("查询成功", applicationStatus);
        } catch (Exception e) {
            logger.error("查询融资申请状态失败", e);
            return error("查询融资申请状态失败: " + e.getMessage());
        }
    }

    /**
     * 实时查询债权流转状态
     * 
     * @param creditId 债权ID
     * @return 实时流转状态
     */
    @PreAuthorize("@ss.hasPermi('data:credit:query')")
    @GetMapping("/credits/{creditId}/realtime-flow")
    public AjaxResult queryRealTimeCreditFlow(@PathVariable("creditId") Long creditId)
    {
        try {
            Map<String, Object> flowStatus = dataQueryService.queryRealTimeCreditFlow(creditId);
            return AjaxResult.success("查询实时流转状态成功", flowStatus);
        } catch (Exception e) {
            logger.error("查询实时流转状态失败", e);
            return error("查询实时流转状态失败: " + e.getMessage());
        }
    }

    /**
     * 查询用户相关的所有债权
     * 
     * @param userId 用户ID
     * @param status 状态过滤
     * @param pageNum 页码
     * @param pageSize 页大小
     * @return 债权列表
     */
    @PreAuthorize("@ss.hasPermi('data:credit:query')")
    @GetMapping("/users/{userId}/credits")
    public AjaxResult queryUserCredits(
            @PathVariable("userId") Long userId,
            @RequestParam(value = "status", required = false) String status,
            @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize)
    {
        try {
            Map<String, Object> userCredits = dataQueryService.queryUserCredits(userId, status, pageNum, pageSize);
            return AjaxResult.success("查询用户债权成功", userCredits);
        } catch (Exception e) {
            logger.error("查询用户债权失败", e);
            return error("查询用户债权失败: " + e.getMessage());
        }
    }

    /**
     * 查询公司相关的债权统计
     * 
     * @param companyId 公司ID
     * @param companyType 公司类型
     * @return 债权统计信息
     */
    @PreAuthorize("@ss.hasPermi('data:company:query')")
    @GetMapping("/companies/{companyId}/credit-statistics")
    public AjaxResult queryCompanyCreditStatistics(
            @PathVariable("companyId") Long companyId,
            @RequestParam("companyType") String companyType)
    {
        try {
            Map<String, Object> statistics = dataQueryService.queryCompanyCreditStatistics(companyId, companyType);
            return AjaxResult.success("查询公司债权统计成功", statistics);
        } catch (Exception e) {
            logger.error("查询公司债权统计失败", e);
            return error("查询公司债权统计失败: " + e.getMessage());
        }
    }

    /**
     * 查询资金流转记录
     * 
     * @param accountId 账户ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 资金流转记录
     */
    @PreAuthorize("@ss.hasPermi('data:fund:query')")
    @GetMapping("/accounts/{accountId}/fund-transfers")
    public AjaxResult queryFundTransferRecords(
            @PathVariable("accountId") Long accountId,
            @RequestParam(value = "startDate", required = false) String startDate,
            @RequestParam(value = "endDate", required = false) String endDate)
    {
        try {
            Date start = parseDate(startDate);
            Date end = parseDate(endDate);
            
            List<Map<String, Object>> records = dataQueryService.queryFundTransferRecords(accountId, start, end);
            return AjaxResult.success("查询资金流转记录成功", records);
        } catch (Exception e) {
            logger.error("查询资金流转记录失败", e);
            return error("查询资金流转记录失败: " + e.getMessage());
        }
    }

    /**
     * 查询系统概览数据
     * 
     * @param userId 用户ID
     * @return 系统概览数据
     */
    @PreAuthorize("@ss.hasPermi('data:overview:query')")
    @GetMapping("/overview")
    public AjaxResult querySystemOverview(@RequestParam(value = "userId", required = false) Long userId)
    {
        try {
            Map<String, Object> overview = dataQueryService.querySystemOverview(userId);
            return AjaxResult.success("查询系统概览成功", overview);
        } catch (Exception e) {
            logger.error("查询系统概览失败", e);
            return error("查询系统概览失败: " + e.getMessage());
        }
    }

    /**
     * 搜索债权信息
     * 
     * @param keyword 关键词
     * @param searchType 搜索类型
     * @param filters 过滤条件
     * @return 搜索结果
     */
    @PreAuthorize("@ss.hasPermi('data:credit:query')")
    @PostMapping("/credits/search")
    public AjaxResult searchCredits(
            @RequestParam("keyword") String keyword,
            @RequestParam(value = "searchType", defaultValue = "all") String searchType,
            @RequestBody(required = false) Map<String, Object> filters)
    {
        try {
            List<Map<String, Object>> results = dataQueryService.searchCredits(keyword, searchType, filters);
            return AjaxResult.success("搜索成功", results);
        } catch (Exception e) {
            logger.error("搜索债权信息失败", e);
            return error("搜索债权信息失败: " + e.getMessage());
        }
    }

    /**
     * 获取实时通知数据
     * 
     * @param userId 用户ID
     * @param notificationType 通知类型
     * @return 通知数据
     */
    @PreAuthorize("@ss.hasPermi('data:notification:query')")
    @GetMapping("/notifications")
    public AjaxResult getRealTimeNotifications(
            @RequestParam(value = "userId", required = false) Long userId,
            @RequestParam(value = "notificationType", required = false) String notificationType)
    {
        try {
            List<Map<String, Object>> notifications = dataQueryService.getRealTimeNotifications(userId, notificationType);
            return AjaxResult.success("获取通知成功", notifications);
        } catch (Exception e) {
            logger.error("获取实时通知失败", e);
            return error("获取实时通知失败: " + e.getMessage());
        }
    }

    /**
     * 订阅实时数据更新
     * 
     * @param subscriptionRequest 订阅请求
     * @return 订阅ID
     */
    @PreAuthorize("@ss.hasPermi('data:subscription:add')")
    @Log(title = "实时数据订阅", businessType = BusinessType.INSERT)
    @PostMapping("/subscriptions")
    public AjaxResult subscribeRealTimeUpdates(@RequestBody Map<String, Object> subscriptionRequest)
    {
        try {
            Long userId = Long.valueOf(subscriptionRequest.get("userId").toString());
            String dataType = subscriptionRequest.get("dataType").toString();
            String callback = subscriptionRequest.get("callback").toString();
            
            String subscriptionId = dataQueryService.subscribeRealTimeUpdates(userId, dataType, callback);
            return AjaxResult.success("订阅成功", subscriptionId);
        } catch (Exception e) {
            logger.error("订阅实时数据更新失败", e);
            return error("订阅实时数据更新失败: " + e.getMessage());
        }
    }

    /**
     * 取消实时数据订阅
     * 
     * @param subscriptionId 订阅ID
     * @return 取消结果
     */
    @PreAuthorize("@ss.hasPermi('data:subscription:remove')")
    @Log(title = "取消实时数据订阅", businessType = BusinessType.DELETE)
    @PostMapping("/subscriptions/{subscriptionId}/unsubscribe")
    public AjaxResult unsubscribeRealTimeUpdates(@PathVariable("subscriptionId") String subscriptionId)
    {
        try {
            boolean result = dataQueryService.unsubscribeRealTimeUpdates(subscriptionId);
            if (result) {
                return AjaxResult.success("取消订阅成功");
            } else {
                return error("订阅不存在或已取消");
            }
        } catch (Exception e) {
            logger.error("取消实时数据订阅失败", e);
            return error("取消实时数据订阅失败: " + e.getMessage());
        }
    }

    /**
     * 获取个性化仪表板配置
     * 
     * @param userId 用户ID
     * @return 仪表板配置
     */
    @PreAuthorize("@ss.hasPermi('data:dashboard:query')")
    @GetMapping("/users/{userId}/dashboard")
    public AjaxResult getPersonalizedDashboard(@PathVariable("userId") Long userId)
    {
        try {
            Map<String, Object> dashboard = dataQueryService.getPersonalizedDashboard(userId);
            return AjaxResult.success("获取仪表板配置成功", dashboard);
        } catch (Exception e) {
            logger.error("获取个性化仪表板配置失败", e);
            return error("获取个性化仪表板配置失败: " + e.getMessage());
        }
    }

    /**
     * 保存个性化仪表板配置
     * 
     * @param userId 用户ID
     * @param dashboardConfig 仪表板配置
     * @return 保存结果
     */
    @PreAuthorize("@ss.hasPermi('data:dashboard:edit')")
    @Log(title = "保存仪表板配置", businessType = BusinessType.UPDATE)
    @PostMapping("/users/{userId}/dashboard")
    public AjaxResult savePersonalizedDashboard(
            @PathVariable("userId") Long userId,
            @RequestBody Map<String, Object> dashboardConfig)
    {
        try {
            boolean result = dataQueryService.savePersonalizedDashboard(userId, dashboardConfig);
            if (result) {
                return AjaxResult.success("保存仪表板配置成功");
            } else {
                return error("保存仪表板配置失败");
            }
        } catch (Exception e) {
            logger.error("保存个性化仪表板配置失败", e);
            return error("保存个性化仪表板配置失败: " + e.getMessage());
        }
    }

    /**
     * 查询数据变更日志
     * 
     * @param entityType 实体类型
     * @param entityId 实体ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 变更日志
     */
    @PreAuthorize("@ss.hasPermi('data:changelog:query')")
    @GetMapping("/changelog")
    public AjaxResult queryDataChangeLog(
            @RequestParam("entityType") String entityType,
            @RequestParam("entityId") Long entityId,
            @RequestParam(value = "startDate", required = false) String startDate,
            @RequestParam(value = "endDate", required = false) String endDate)
    {
        try {
            Date start = parseDate(startDate);
            Date end = parseDate(endDate);
            
            List<Map<String, Object>> changelog = dataQueryService.queryDataChangeLog(entityType, entityId, start, end);
            return AjaxResult.success("查询变更日志成功", changelog);
        } catch (Exception e) {
            logger.error("查询数据变更日志失败", e);
            return error("查询数据变更日志失败: " + e.getMessage());
        }
    }

    /**
     * 获取数据统计摘要
     * 
     * @param statisticsType 统计类型
     * @param timeRange 时间范围
     * @return 统计摘要
     */
    @PreAuthorize("@ss.hasPermi('data:statistics:query')")
    @GetMapping("/statistics/summary")
    public AjaxResult getDataStatisticsSummary(
            @RequestParam("statisticsType") String statisticsType,
            @RequestParam(value = "timeRange", defaultValue = "30d") String timeRange)
    {
        try {
            Map<String, Object> summary = dataQueryService.getDataStatisticsSummary(statisticsType, timeRange);
            return AjaxResult.success("获取统计摘要成功", summary);
        } catch (Exception e) {
            logger.error("获取数据统计摘要失败", e);
            return error("获取数据统计摘要失败: " + e.getMessage());
        }
    }

    /**
     * 查询预警信息
     * 
     * @param userId 用户ID
     * @param alertType 预警类型
     * @param severity 严重程度
     * @return 预警信息列表
     */
    @PreAuthorize("@ss.hasPermi('data:alert:query')")
    @GetMapping("/alerts")
    public AjaxResult queryAlerts(
            @RequestParam(value = "userId", required = false) Long userId,
            @RequestParam(value = "alertType", required = false) String alertType,
            @RequestParam(value = "severity", required = false) String severity)
    {
        try {
            List<Map<String, Object>> alerts = dataQueryService.queryAlerts(userId, alertType, severity);
            return AjaxResult.success("查询预警信息成功", alerts);
        } catch (Exception e) {
            logger.error("查询预警信息失败", e);
            return error("查询预警信息失败: " + e.getMessage());
        }
    }

    /**
     * 标记预警为已读
     * 
     * @param alertId 预警ID
     * @param userId 用户ID
     * @return 标记结果
     */
    @PreAuthorize("@ss.hasPermi('data:alert:edit')")
    @Log(title = "标记预警已读", businessType = BusinessType.UPDATE)
    @PostMapping("/alerts/{alertId}/mark-read")
    public AjaxResult markAlertAsRead(
            @PathVariable("alertId") Long alertId,
            @RequestParam("userId") Long userId)
    {
        try {
            boolean result = dataQueryService.markAlertAsRead(alertId, userId);
            if (result) {
                return AjaxResult.success("标记预警已读成功");
            } else {
                return error("标记预警已读失败");
            }
        } catch (Exception e) {
            logger.error("标记预警已读失败", e);
            return error("标记预警已读失败: " + e.getMessage());
        }
    }

    /**
     * 解析日期参数
     */
    private Date parseDate(String dateStr) {
        if (dateStr == null || dateStr.isEmpty()) {
            return null;
        }
        
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            return sdf.parse(dateStr);
        } catch (ParseException e) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                return sdf.parse(dateStr);
            } catch (ParseException ex) {
                logger.warn("无法解析日期格式: {}", dateStr);
                return null;
            }
        }
    }
}