package com.imdroid.beidou.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONObject;
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.imdroid.secapi.dto.*;
import org.apache.http.HttpEntity;
import org.apache.http.util.EntityUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletResponse;
import java.security.MessageDigest;
import java.util.*;
import java.net.URLEncoder;

@Controller
public class SimCardController extends BasicController  {
    @Value("${sim.url}")
    private String BASE_URL;
    @Value("${sim.username}")
    private String USERNAME;
    @Value("${sim.key}")
    private String KEY;

    @Autowired
    private GnssDeviceMapper gnssDeviceMapper;
    
    @Autowired
    private TrafficCardMapper trafficCardMapper;
    
    @Autowired
    private TrafficDeviceMappingMapper trafficDeviceMappingMapper;

    @Autowired
    private TrafficRecordMapper trafficRecordMapper;

    @RequestMapping("/page/sim_status")
    public String simStatus(Model m, HttpSession session) {
        initModel(m, session);

        return "/page/sim_status";
    }

    @RequestMapping("/page/sim_traffic_records")
    public String simTrafficRecords(Model m, HttpSession session) {
        initModel(m, session);

        return "/page/sim_traffic_records";
    }

    @RequestMapping("/page/sim_device_mapping")
    public String simDeviceMapping(Model m, HttpSession session) {
        initModel(m, session);

        return "/page/sim_device_mapping";
    }

    @RequestMapping("/sim/list")
    @ResponseBody
    public JSONObject list(HttpSession session,
                           int page,
                           int limit,
                           String searchType,
                           String searchContent,
                           Integer status) {

        QueryWrapper<GnssDevice> deviceQueryWrapper = new QueryWrapper<>();

        if (!StringUtils.isEmpty(searchContent)) {
            switch(searchType) {
                case "deviceId":
                    deviceQueryWrapper.like("deviceid", searchContent.trim());
                    break;
                case "iccid":
                    deviceQueryWrapper.like("iccid", searchContent.trim());
                    break;
                case "imei":
                    deviceQueryWrapper.like("imei", searchContent.trim());
                    break;
                case "simNumber":
                    // 通过SIM号查找对应的ICCID，然后查询设备
                    TrafficCard cardByMsisdn = trafficCardMapper.selectOne(
                        new QueryWrapper<TrafficCard>().like("msisdn", searchContent.trim())
                    );
                    if (cardByMsisdn != null) {
                        deviceQueryWrapper.eq("iccid", cardByMsisdn.getIccid());
                    } else {
                        deviceQueryWrapper.eq("iccid", "");
                    }
                    break;
            }
        }

        // 只查询有ICCID的设备
        deviceQueryWrapper.isNotNull("iccid");
        deviceQueryWrapper.ne("iccid", "");

        if (status != null) {
            List<TrafficCard> cardsWithStatus = trafficCardMapper.selectList(
                new QueryWrapper<TrafficCard>().eq("status", status)
            );
            if (cardsWithStatus.isEmpty()) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("code", 0);
                jsonObject.put("msg", "");
                jsonObject.put("count", 0);
                jsonObject.put("data", new ArrayList<>());
                return jsonObject;
            }
            
            List<String> iccids = new ArrayList<>();
            for (TrafficCard card : cardsWithStatus) {
                iccids.add(card.getIccid());
            }
            deviceQueryWrapper.in("iccid", iccids);
        }
        
        deviceQueryWrapper.orderByDesc("deviceid");
        
        Page<GnssDevice> pageable = new Page<>(page, limit);
        IPage<GnssDevice> devices = gnssDeviceMapper.selectPage(pageable, deviceQueryWrapper);

        List<Map<String, Object>> enrichedData = new ArrayList<>();
        for (GnssDevice device : devices.getRecords()) {
            TrafficCard trafficCard = null;
            if (device.getIccid() != null && !device.getIccid().trim().isEmpty()) {
                trafficCard = trafficCardMapper.findByIccid(device.getIccid());
            }
            
            Map<String, Object> deviceData = new HashMap<>();
            deviceData.put("id", device.getId());
            deviceData.put("deviceid", device.getDeviceid());
            deviceData.put("iccid", device.getIccid());
            deviceData.put("imei", device.getImei());
            
            if (trafficCard != null) {
                deviceData.put("msisdn", trafficCard.getMsisdn());
                deviceData.put("status", trafficCard.getStatus());
                deviceData.put("remaining", trafficCard.getRemaining());
                deviceData.put("total", trafficCard.getTotal());
                deviceData.put("used", trafficCard.getUsed());
                deviceData.put("updateTime", trafficCard.getUpdatetime());
                deviceData.put("queryStatus", trafficCard.getQuerystatus());
            } else {
                deviceData.put("msisdn", "-");
                deviceData.put("status", TrafficCard.STATUS_UNKNOWN);
                deviceData.put("remaining", 0);
                deviceData.put("total", 0);
                deviceData.put("used", 0);
                deviceData.put("updateTime", null);
                deviceData.put("queryStatus", TrafficCard.QUERY_STATUS_NORMAL);
            }
            
            enrichedData.add(deviceData);
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", 0);
        jsonObject.put("msg", "");
        jsonObject.put("count", devices.getTotal());
        jsonObject.put("data", enrichedData);
        return jsonObject;
    }

    @RequestMapping("/page/sim_traffic_query")
    public String simTrafficQuery(Model m, HttpSession session) {
        initModel(m, session);

        return "/page/sim_traffic_query";
    }

    // 代理转发
    @RequestMapping("/api/proxy/sim/query")
    @ResponseBody
    public JSONObject proxySimQuery(
            @RequestParam String type,
            @RequestParam String content
    ){
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        try {
            Map<String, String> params = new HashMap<>();
            params.put("username", USERNAME);
            params.put("key", KEY);

            switch(type) {
                case "iccid":
                    params.put("card", content);
                    break;
                case "deviceId":
                    if (content.trim().isEmpty()) {
                        throw new IllegalArgumentException("设备ID不能为空");
                    }
                    GnssDevice device = gnssDeviceMapper.queryByDeviceId(content.trim());
                    if (device == null || device.getIccid() == null || device.getIccid().trim().isEmpty()) {
                        throw new IllegalArgumentException("未找到该设备ID或设备没有ICCID信息");
                    }
                    params.put("card", device.getIccid());
                    break;
                case "imei":
                    if (content.trim().isEmpty()) {
                        throw new IllegalArgumentException("IMEI不能为空");
                    }
                    QueryWrapper<GnssDevice> deviceByImeiQueryWrapper = new QueryWrapper<>();
                    deviceByImeiQueryWrapper.eq("imei", content.trim());
                    deviceByImeiQueryWrapper.last("limit 1");
                    GnssDevice deviceByImei = gnssDeviceMapper.selectOne(deviceByImeiQueryWrapper);
                    if (deviceByImei == null || deviceByImei.getIccid() == null || deviceByImei.getIccid().trim().isEmpty()) {
                        throw new IllegalArgumentException("未找到该IMEI对应的设备或设备没有ICCID信息");
                    }
                    params.put("card", deviceByImei.getIccid());
                    break;
                case "simNumber":
                    params.put("card", content);
                    break;
                default:
                    throw new IllegalArgumentException("无效的查询类型: " + type);
            }

            params.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));

            String signature = calculateSignature(params);
            if (signature == null) {
                throw new Exception("签名计算失败");
            }

            StringBuilder urlBuilder = new StringBuilder(BASE_URL);
            urlBuilder.append("/api/Service/QueryCard?");
            urlBuilder.append("username=").append(USERNAME);
            urlBuilder.append("&key=").append(KEY);
            urlBuilder.append("&card=").append(params.get("card"));
            urlBuilder.append("&timestamp=").append(params.get("timestamp"));
            urlBuilder.append("&signature=").append(signature);

            httpClient = HttpClients.createDefault();
            HttpGet httpGet = new HttpGet(urlBuilder.toString());

            // System.out.println("Sending request: " + urlBuilder.toString());
            response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();


            String result = EntityUtils.toString(entity);
            // System.out.println("Received response: " + result);

            return JSONObject.parseObject(result);

        } catch (Exception e) {
            // System.out.println("Query failed: " + e.getMessage());
            JSONObject errorResponse = new JSONObject();
            errorResponse.put("Status", 0);
            errorResponse.put("Message", "查询失败: " + e.getMessage());
            return errorResponse;

        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (Exception e) {

            }
        }
    }

    @RequestMapping("/sim/traffic-records")
    @ResponseBody
    public JSONObject getTrafficRecords(HttpSession session,
                                        int page,
                                        int limit,
                                        String searchType,
                                        String searchContent,
                                        String startTime,
                                        String endTime) {
        try {
            Page<TrafficRecord> pageable = new Page<>(page, limit);
            QueryWrapper<TrafficRecord> queryWrapper = new QueryWrapper<>();

            if (!StringUtils.isEmpty(searchContent)) {
                switch(searchType) {
                    case "deviceId":
                        GnssDevice device = gnssDeviceMapper.queryByDeviceId(searchContent.trim());
                        if (device != null && device.getIccid() != null && !device.getIccid().trim().isEmpty()) {
                            queryWrapper.eq("iccid", device.getIccid());
                        } else {
                            queryWrapper.eq("iccid", "");
                        }
                        break;
                    case "iccid":
                        queryWrapper.like("iccid", searchContent.trim());
                        break;
                    case "imei":
                        QueryWrapper<GnssDevice> deviceByImeiQueryWrapper = new QueryWrapper<>();
                        deviceByImeiQueryWrapper.eq("imei", searchContent.trim());
                        deviceByImeiQueryWrapper.last("limit 1");
                        GnssDevice deviceByImei = gnssDeviceMapper.selectOne(deviceByImeiQueryWrapper);
                        if (deviceByImei != null && deviceByImei.getIccid() != null && !deviceByImei.getIccid().trim().isEmpty()) {
                            queryWrapper.eq("iccid", deviceByImei.getIccid());
                        } else {
                            queryWrapper.eq("iccid", "");
                        }
                        break;
                    case "simNumber":
                        TrafficCard cardByMsisdn = trafficCardMapper.selectOne(
                            new QueryWrapper<TrafficCard>().like("msisdn", searchContent.trim())
                        );
                        if (cardByMsisdn != null) {
                            queryWrapper.eq("iccid", cardByMsisdn.getIccid());
                        } else {
                            queryWrapper.eq("iccid", "");
                        }
                        break;
                }
            }

            if (!StringUtils.isEmpty(startTime)) {
                queryWrapper.ge("recordtime", startTime);
            }
            if (!StringUtils.isEmpty(endTime)) {
                queryWrapper.le("recordtime", endTime);
            }

            queryWrapper.orderByDesc("recordtime");
            IPage<TrafficRecord> records = trafficRecordMapper.selectPage(pageable, queryWrapper);

            List<Map<String, Object>> enrichedData = new ArrayList<>();
            for (TrafficRecord record : records.getRecords()) {
                Map<String, Object> recordData = new HashMap<>();
                recordData.put("id", record.getId());
                recordData.put("iccid", record.getIccid());
                recordData.put("recordTime", record.getRecordtime());
                recordData.put("remaining", record.getRemaining());
                recordData.put("total", record.getTotal());
                recordData.put("used", record.getUsed());
                
                GnssDevice device = gnssDeviceMapper.selectOne(
                    new QueryWrapper<GnssDevice>().eq("iccid", record.getIccid())
                );
                if (device != null) {
                    recordData.put("deviceid", device.getDeviceid());
                } else {
                    recordData.put("deviceid", "无绑定设备");
                }
                
                TrafficCard trafficCard = trafficCardMapper.findByIccid(record.getIccid());
                if (trafficCard != null) {
                    recordData.put("msisdn", trafficCard.getMsisdn());
                } else {
                    recordData.put("msisdn", "-");
                }
                
                enrichedData.add(recordData);
            }

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", 0);
            jsonObject.put("msg", "");
            jsonObject.put("count", records.getTotal());
            jsonObject.put("data", enrichedData);
            return jsonObject;

        } catch (Exception e) {
            JSONObject errorResponse = new JSONObject();
            errorResponse.put("code", 1);
            errorResponse.put("msg", "查询失败: " + e.getMessage());
            errorResponse.put("count", 0);
            errorResponse.put("data", new ArrayList<>());
            return errorResponse;
        }
    }

    @RequestMapping("/sim/device-mapping")
    @ResponseBody
    public JSONObject getDeviceMapping(HttpSession session,
                                       int page,
                                       int limit,
                                       String searchType,
                                       String searchContent) {
        try {
            Page<TrafficDeviceMapping> pageable = new Page<>(page, limit);
            QueryWrapper<TrafficDeviceMapping> queryWrapper = new QueryWrapper<>();

            if (!StringUtils.isEmpty(searchContent)) {
                switch(searchType) {
                    case "deviceId":
                        queryWrapper.like("deviceid", searchContent.trim());
                        break;
                    case "iccid":
                        queryWrapper.like("iccid", searchContent.trim());
                        break;
                    case "imei":
                        QueryWrapper<GnssDevice> deviceByImeiQueryWrapper = new QueryWrapper<>();
                        deviceByImeiQueryWrapper.eq("imei", searchContent.trim());
                        deviceByImeiQueryWrapper.last("limit 1");
                        GnssDevice deviceByImei = gnssDeviceMapper.selectOne(deviceByImeiQueryWrapper);
                        if (deviceByImei != null && deviceByImei.getIccid() != null && !deviceByImei.getIccid().trim().isEmpty()) {
                            queryWrapper.eq("iccid", deviceByImei.getIccid());
                        } else {
                            queryWrapper.eq("iccid", "");
                        }
                        break;
                    case "simNumber":
                        TrafficCard cardByMsisdn = trafficCardMapper.selectOne(
                            new QueryWrapper<TrafficCard>().like("msisdn", searchContent.trim())
                        );
                        if (cardByMsisdn != null) {
                            queryWrapper.eq("iccid", cardByMsisdn.getIccid());
                        } else {
                            queryWrapper.eq("iccid", "");
                        }
                        break;
                }
            }

            queryWrapper.orderByDesc("starttime");
            IPage<TrafficDeviceMapping> mappings = trafficDeviceMappingMapper.selectPage(pageable, queryWrapper);

            List<Map<String, Object>> enrichedData = new ArrayList<>();
            for (TrafficDeviceMapping mapping : mappings.getRecords()) {
                Map<String, Object> mappingData = new HashMap<>();
                mappingData.put("id", mapping.getId());
                mappingData.put("deviceId", mapping.getDeviceid());
                mappingData.put("iccid", mapping.getIccid());
                mappingData.put("startTime", mapping.getStarttime());
                mappingData.put("endTime", mapping.getEndtime());
                
                mappingData.put("isActive", mapping.getEndtime() == null);
                
                // 查找对应的流量卡信息
                TrafficCard trafficCard = trafficCardMapper.findByIccid(mapping.getIccid());
                if (trafficCard != null) {
                    mappingData.put("msisdn", trafficCard.getMsisdn());
                } else {
                    mappingData.put("msisdn", "-");
                }
                
                enrichedData.add(mappingData);
            }

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", 0);
            jsonObject.put("msg", "");
            jsonObject.put("count", mappings.getTotal());
            jsonObject.put("data", enrichedData);
            return jsonObject;

        } catch (Exception e) {
            JSONObject errorResponse = new JSONObject();
            errorResponse.put("code", 1);
            errorResponse.put("msg", "查询失败: " + e.getMessage());
            errorResponse.put("count", 0);
            errorResponse.put("data", new ArrayList<>());
            return errorResponse;
        }
    }

    private String calculateSignature(Map<String, String> params) {
        try {
            List<String> paramList = new ArrayList<>();
            for (Map.Entry<String, String> entry : params.entrySet()) {
                paramList.add(entry.getKey() + "=" + entry.getValue());
            }
            Collections.sort(paramList);

            String paramString = String.join("&", paramList);
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(paramString.getBytes());
            StringBuilder sb = new StringBuilder();
            for (byte b : digest) {
                sb.append(String.format("%02x", b));
            }
            String signature = sb.toString();
            // System.out.println("Signature: " + signature);
            return signature;

        } catch (Exception e) {
            //System.out.println("Signature: " + e.getMessage());
            return null;
        }
    }

    @RequestMapping("/sim/export")
    @ResponseBody
    public void exportSimList(HttpServletResponse response, String searchType, String searchContent, Integer status, Boolean exportAll, Integer pageSize) {
        try {
            System.out.println("开始导出SIM卡数据, 参数: searchType=" + searchType + ", searchContent=" + searchContent + 
                            ", status=" + status + ", exportAll=" + exportAll + ", pageSize=" + pageSize);

            QueryWrapper<GnssDevice> deviceQueryWrapper = new QueryWrapper<>();

            if (!StringUtils.isEmpty(searchContent)) {
                switch(searchType) {
                    case "deviceId":
                        deviceQueryWrapper.like("deviceid", searchContent.trim());
                        break;
                    case "iccid":
                        deviceQueryWrapper.like("iccid", searchContent.trim());
                        break;
                    case "imei":
                        deviceQueryWrapper.like("imei", searchContent.trim());
                        break;
                    case "simNumber":
                        // 通过SIM号查找对应的ICCID，然后查询设备
                        TrafficCard cardByMsisdn = trafficCardMapper.selectOne(
                            new QueryWrapper<TrafficCard>().like("msisdn", searchContent.trim())
                        );
                        if (cardByMsisdn != null) {
                            deviceQueryWrapper.eq("iccid", cardByMsisdn.getIccid());
                        } else {
                            deviceQueryWrapper.eq("iccid", "");
                        }
                        break;
                }
            }

            deviceQueryWrapper.isNotNull("iccid");
            deviceQueryWrapper.ne("iccid", "");

            if (status != null) {
                List<TrafficCard> cardsWithStatus = trafficCardMapper.selectList(
                    new QueryWrapper<TrafficCard>().eq("status", status)
                );
                if (!cardsWithStatus.isEmpty()) {
                    List<String> iccids = new ArrayList<>();
                    for (TrafficCard card : cardsWithStatus) {
                        iccids.add(card.getIccid());
                    }
                    deviceQueryWrapper.in("iccid", iccids);
                } else {
                    deviceQueryWrapper.eq("iccid", "不存在的ICCID");
                }
            }
            
            deviceQueryWrapper.orderByDesc("deviceid");
            
            List<GnssDevice> devices;
            if (Boolean.TRUE.equals(exportAll)) {
                devices = gnssDeviceMapper.selectList(deviceQueryWrapper);
            } else {
                int limit = pageSize != null && pageSize > 0 ? pageSize : 20; // 默认20条，与前端表格默认一致
                Page<GnssDevice> pageable = new Page<>(1, limit);
                IPage<GnssDevice> devicePage = gnssDeviceMapper.selectPage(pageable, deviceQueryWrapper);
                devices = devicePage.getRecords();
            }
            
            if (devices.isEmpty()) {
                devices = new ArrayList<>();
                GnssDevice emptyDevice = new GnssDevice();
                emptyDevice.setDeviceid("无数据");
                emptyDevice.setIccid("");
                devices.add(emptyDevice);
            }

            List<List<Object>> exportList = new ArrayList<>();
            List<String> headList = Arrays.asList("设备号", "ICCID", "SIM卡号", "IMEI", "状态",
                                               "剩余流量(MB)", "总流量(MB)", "已用流量(MB)", "更新时间");
                                               
            for (GnssDevice device : devices) {
                List<Object> rowData = new ArrayList<>();
                rowData.add(device.getDeviceid());
                rowData.add(device.getIccid());
                
                TrafficCard trafficCard = null;
                if (device.getIccid() != null && !device.getIccid().trim().isEmpty()) {
                    trafficCard = trafficCardMapper.findByIccid(device.getIccid());
                }
                
                if (trafficCard != null) {
                    rowData.add(trafficCard.getMsisdn()); // SIM卡号
                    rowData.add(device.getImei() != null ? device.getImei() : ""); // IMEI
                    
                    String statusStr;
                    switch(trafficCard.getStatus()) {
                        case 1: statusStr = "待激活"; break;
                        case 2: statusStr = "已激活"; break;
                        case 3: statusStr = "停机"; break;
                        case 4: statusStr = "注销"; break;
                        case 5: statusStr = "库存"; break;
                        case 6: statusStr = "可测试"; break;
                        case 7: statusStr = "失效"; break;
                        default: statusStr = "未知";
                    }
                    rowData.add(statusStr);
                    // 单位转换：从KB到MB
                    rowData.add(trafficCard.getRemaining() != null ? 
                            String.format("%.2f", trafficCard.getRemaining() / 1000.0) : "0"); // 剩余流量
                    rowData.add(trafficCard.getTotal() != null ? 
                            String.format("%.2f", trafficCard.getTotal() / 1000.0) : "0"); // 总流量
                    rowData.add(trafficCard.getUsed() != null ? 
                            String.format("%.2f", trafficCard.getUsed() / 1000.0) : "0"); // 已用流量
                    rowData.add(trafficCard.getUpdatetime()); // 更新时间
                } else {
                    rowData.add("-"); // SIM卡号
                    rowData.add(device.getImei() != null ? device.getImei() : ""); // IMEI
                    rowData.add("未知"); // 状态
                    rowData.add("0"); // 剩余流量
                    rowData.add("0"); // 总流量
                    rowData.add("0"); // 已用流量
                    rowData.add(""); // 更新时间
                }
                
                exportList.add(rowData);
            }

            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("SIM卡信息", "UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
            
            EasyExcel.write(response.getOutputStream())
                    .head(createExcelHead(headList))
                    .sheet("SIM卡信息")
                    .doWrite(exportList);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private List<List<String>> createExcelHead(List<String> headList) {
        List<List<String>> result = new ArrayList<>();
        for (String head : headList) {
            List<String> column = new ArrayList<>();
            column.add(head);
            result.add(column);
        }
        return result;
    }

    @RequestMapping("/sim/traffic-records/export")
    @ResponseBody
    public void exportTrafficRecords(HttpServletResponse response, String searchType, String searchContent, String startTime, String endTime) {
        try {
            System.out.println("开始导出SIM卡流量记录, 参数: searchType=" + searchType + ", searchContent=" + searchContent + 
                              ", startTime=" + startTime + ", endTime=" + endTime);
            
            QueryWrapper<TrafficRecord> queryWrapper = new QueryWrapper<>();

            if (!StringUtils.isEmpty(searchContent)) {
                switch(searchType) {
                    case "deviceId":
                        GnssDevice device = gnssDeviceMapper.queryByDeviceId(searchContent.trim());
                        if (device != null && device.getIccid() != null && !device.getIccid().trim().isEmpty()) {
                            queryWrapper.eq("iccid", device.getIccid());
                        } else {
                            queryWrapper.eq("iccid", "");
                        }
                        break;
                    case "iccid":
                        queryWrapper.like("iccid", searchContent.trim());
                        break;
                    case "imei":
                        QueryWrapper<GnssDevice> deviceByImeiQueryWrapper = new QueryWrapper<>();
                        deviceByImeiQueryWrapper.eq("imei", searchContent.trim());
                        deviceByImeiQueryWrapper.last("limit 1");
                        GnssDevice deviceByImei = gnssDeviceMapper.selectOne(deviceByImeiQueryWrapper);
                        if (deviceByImei != null && deviceByImei.getIccid() != null && !deviceByImei.getIccid().trim().isEmpty()) {
                            queryWrapper.eq("iccid", deviceByImei.getIccid());
                        } else {
                            queryWrapper.eq("iccid", "");
                        }
                        break;
                    case "simNumber":
                        TrafficCard cardByMsisdn = trafficCardMapper.selectOne(
                            new QueryWrapper<TrafficCard>().like("msisdn", searchContent.trim())
                        );
                        if (cardByMsisdn != null) {
                            queryWrapper.eq("iccid", cardByMsisdn.getIccid());
                        } else {
                            queryWrapper.eq("iccid", "");
                        }
                        break;
                }
            }

            if (!StringUtils.isEmpty(startTime)) {
                queryWrapper.ge("recordtime", startTime);
            }
            if (!StringUtils.isEmpty(endTime)) {
                queryWrapper.le("recordtime", endTime);
            }

            queryWrapper.orderByDesc("recordtime");
            
            List<TrafficRecord> records = trafficRecordMapper.selectList(queryWrapper);
            
            System.out.println("查询到流量记录数量: " + records.size());
            if (records.isEmpty()) {
                records = new ArrayList<>();
                TrafficRecord emptyRecord = new TrafficRecord();
                emptyRecord.setIccid("无数据");
                records.add(emptyRecord);
            }

            List<List<Object>> exportList = new ArrayList<>();
            List<String> headList = Arrays.asList("设备号", "ICCID", "SIM卡号", "记录时间",
                                               "剩余流量(MB)", "总流量(MB)", "已用流量(MB)");
                                               
            for (TrafficRecord record : records) {
                List<Object> rowData = new ArrayList<>();
                
                GnssDevice device = gnssDeviceMapper.selectOne(
                    new QueryWrapper<GnssDevice>().eq("iccid", record.getIccid())
                );
                rowData.add(device != null ? device.getDeviceid() : "无绑定设备"); // 设备号
                rowData.add(record.getIccid()); // ICCID
                
                TrafficCard trafficCard = trafficCardMapper.findByIccid(record.getIccid());
                rowData.add(trafficCard != null ? trafficCard.getMsisdn() : "-"); // SIM卡号
                
                rowData.add(record.getRecordtime()); // 记录时间
                
                rowData.add(record.getRemaining() != null ?
                        String.format("%.2f", record.getRemaining() / 1000.0) : "0"); // 剩余流量
                rowData.add(record.getTotal() != null ? 
                        String.format("%.2f", record.getTotal() / 1000.0) : "0"); // 总流量
                rowData.add(record.getUsed() != null ? 
                        String.format("%.2f", record.getUsed() / 1000.0) : "0"); // 已用流量
                
                exportList.add(rowData);
            }

            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("SIM卡流量记录", "UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
            
            EasyExcel.write(response.getOutputStream())
                    .head(createExcelHead(headList))
                    .sheet("SIM卡流量记录")
                    .doWrite(exportList);
                    
            System.out.println("导出完成，流量记录数: " + exportList.size());

        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("导出流量记录失败: " + e.getMessage());
        }
    }
    
    @RequestMapping("/sim/device-mapping/export")
    @ResponseBody
    public void exportDeviceMapping(HttpServletResponse response, String searchType, String searchContent) {
        try {
            QueryWrapper<TrafficDeviceMapping> queryWrapper = new QueryWrapper<>();

            if (!StringUtils.isEmpty(searchContent)) {
                switch(searchType) {
                    case "deviceId":
                        queryWrapper.like("deviceid", searchContent.trim());
                        break;
                    case "iccid":
                        queryWrapper.like("iccid", searchContent.trim());
                        break;
                    case "imei":
                        QueryWrapper<GnssDevice> deviceByImeiQueryWrapper = new QueryWrapper<>();
                        deviceByImeiQueryWrapper.eq("imei", searchContent.trim());
                        deviceByImeiQueryWrapper.last("limit 1");
                        GnssDevice deviceByImei = gnssDeviceMapper.selectOne(deviceByImeiQueryWrapper);
                        if (deviceByImei != null && deviceByImei.getIccid() != null && !deviceByImei.getIccid().trim().isEmpty()) {
                            queryWrapper.eq("iccid", deviceByImei.getIccid());
                        } else {
                            queryWrapper.eq("iccid", "");
                        }
                        break;
                    case "simNumber":
                        TrafficCard cardByMsisdn = trafficCardMapper.selectOne(
                            new QueryWrapper<TrafficCard>().like("msisdn", searchContent.trim())
                        );
                        if (cardByMsisdn != null) {
                            queryWrapper.eq("iccid", cardByMsisdn.getIccid());
                        } else {
                            queryWrapper.eq("iccid", "");
                        }
                        break;
                }
            }

            queryWrapper.orderByDesc("starttime");
            
            List<TrafficDeviceMapping> mappings = trafficDeviceMappingMapper.selectList(queryWrapper);
            
            if (mappings.isEmpty()) {
                mappings = new ArrayList<>();
                TrafficDeviceMapping emptyMapping = new TrafficDeviceMapping();
                emptyMapping.setDeviceid("无数据");
                emptyMapping.setIccid("无数据");
                mappings.add(emptyMapping);
            }

            List<List<Object>> exportList = new ArrayList<>();
            List<String> headList = Arrays.asList("设备号", "ICCID", "SIM卡号", "开始时间", "结束时间", "是否激活");
                                               
            for (TrafficDeviceMapping mapping : mappings) {
                List<Object> rowData = new ArrayList<>();
                
                rowData.add(mapping.getDeviceid()); // 设备号
                rowData.add(mapping.getIccid());    // ICCID
                
                TrafficCard trafficCard = trafficCardMapper.findByIccid(mapping.getIccid());
                rowData.add(trafficCard != null ? trafficCard.getMsisdn() : "-"); // SIM卡号
                
                rowData.add(mapping.getStarttime()); // 开始时间
                rowData.add(mapping.getEndtime());   // 结束时间
                rowData.add(mapping.getEndtime() == null ? "是" : "否"); // 是否激活
                
                exportList.add(rowData);
            }

            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("设备SIM卡映射记录", "UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
            
            EasyExcel.write(response.getOutputStream())
                    .head(createExcelHead(headList))
                    .sheet("设备SIM卡映射记录")
                    .doWrite(exportList);
                    
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("导出设备映射记录失败: " + e.getMessage());
        }
    }

    @RequestMapping("/sim/query/export")
    @ResponseBody
    public void exportSimDetail(HttpServletResponse response, String type, String content) {
        try {
            JSONObject apiResult = proxySimQuery(type, content);
            
            if (apiResult.getInteger("Status") != 1 || apiResult.getJSONObject("Data") == null) {
                response.setContentType("text/html;charset=utf-8");
                response.getWriter().write("查询失败: " + apiResult.getString("Message"));
                return;
            }
            
            JSONObject cardData = apiResult.getJSONObject("Data");
            List<List<Object>> exportList = new ArrayList<>();
            
            List<Object> basicInfo = new ArrayList<>();
            basicInfo.add("基本信息");
            basicInfo.add("");
            exportList.add(basicInfo);
            
            addExportRow(exportList, "运营商", getOperatorText(cardData.getInteger("operatortype")));
            addExportRow(exportList, "ICCID", cardData.getString("iccid"));
            addExportRow(exportList, "SIM卡号", cardData.getString("msisdn"));
            addExportRow(exportList, "IMSI", cardData.getString("imsi"));
            
            addExportRow(exportList, "套餐信息", "");
            addExportRow(exportList, "套餐ID", cardData.getString("packageid"));
            addExportRow(exportList, "套餐名称", cardData.getString("packagename"));
            
            addExportRow(exportList, "时间信息", "");
            addExportRow(exportList, "激活时间", cardData.getString("activetime"));
            addExportRow(exportList, "开始时间", cardData.getString("starttime"));
            addExportRow(exportList, "结束时间", cardData.getString("stoptime"));
            addExportRow(exportList, "沉默期结束", cardData.getString("silentdate"));
            
            addExportRow(exportList, "状态", getStatusText(cardData.getInteger("status")));
            
            // APN信息
            if (cardData.getJSONObject("apn") != null) {
                JSONObject apn = cardData.getJSONObject("apn");
                addExportRow(exportList, "APN信息", "");
                addExportRow(exportList, "APN ID", apn.getString("apnid"));
                addExportRow(exportList, "状态", apn.getString("status").equals("01") ? "在线" : "离线");
                addExportRow(exportList, "IP", apn.getString("ip"));
                addExportRow(exportList, "网络", getNetworkText(apn.getString("rat")));
                addExportRow(exportList, "设备状态", apn.getString("onoffstatus").equals("1") ? "开机" : "关机");
            }
            
            // GPRS流量
            if (cardData.getJSONObject("gprs") != null) {
                JSONObject gprs = cardData.getJSONObject("gprs");
                addExportRow(exportList, "GPRS流量", "");
                addExportRow(exportList, "总流量(MB)", formatDouble(parseDouble(gprs.getString("total"))));
                addExportRow(exportList, "已用流量(MB)", formatDouble(parseDouble(gprs.getString("used"))));
                addExportRow(exportList, "剩余流量(MB)", formatDouble(parseDouble(gprs.getString("left"))));
            }

            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("SIM卡详情-" + content, "UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
            
            List<List<String>> head = new ArrayList<>();
            List<String> keyHead = new ArrayList<>();
            keyHead.add("属性");
            head.add(keyHead);
            
            List<String> valueHead = new ArrayList<>();
            valueHead.add("值");
            head.add(valueHead);
            
            EasyExcel.write(response.getOutputStream())
                    .head(head)
                    .sheet("SIM卡详情")
                    .doWrite(exportList);
                    
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("导出SIM卡详情失败: " + e.getMessage());
        }
    }
    
    private void addExportRow(List<List<Object>> exportList, String key, String value) {
        List<Object> row = new ArrayList<>();
        row.add(key);
        row.add(value != null ? value : "");
        exportList.add(row);
    }
    
    private String getOperatorText(Integer type) {
        if (type == null) return "未知运营商";
        switch(type) {
            case 1: return "中国移动";
            case 2: return "中国联通";
            case 3: return "中国电信";
            default: return "未知运营商";
        }
    }
    
    private String getStatusText(Integer status) {
        if (status == null) return "未知状态";
        switch(status) {
            case 1: return "待激活";
            case 2: return "已激活";
            case 3: return "停机";
            case 4: return "注销";
            case 5: return "库存";
            case 6: return "可测试";
            case 7: return "失效";
            default: return "未知状态";
        }
    }
    
    private String getNetworkText(String rat) {
        if (rat == null) return "未知网络";
        switch(rat) {
            case "1": return "3G";
            case "2": return "2G";
            case "6": return "4G";
            case "8": return "NB";
            default: return "未知网络";
        }
    }
    
    private double parseDouble(String value) {
        try {
            return value != null ? Double.parseDouble(value) : 0.0;
        } catch (Exception e) {
            return 0.0;
        }
    }
    
    private String formatDouble(double value) {
        return String.format("%.2f", value);
    }

}


