/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the yifu4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */
package com.yifu.cloud.plus.v1.yifu.social.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.excel.util.ListUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.*;
import com.yifu.cloud.plus.v1.yifu.salary.vo.TSalaryAccountExportByEkpVo;
import com.yifu.cloud.plus.v1.yifu.social.config.SocialConfig;
import com.yifu.cloud.plus.v1.yifu.social.entity.TSocialInfo;
import com.yifu.cloud.plus.v1.yifu.social.mapper.TSocialInfoMapper;
import com.yifu.cloud.plus.v1.yifu.social.service.TDispatchInfoService;
import com.yifu.cloud.plus.v1.yifu.social.service.TSocialSoldierService;
import com.yifu.cloud.plus.v1.yifu.social.vo.SocialHandleExportVo;
import com.yifu.cloud.plus.v1.yifu.social.vo.SocialHandleSearchVo;
import com.yifu.cloud.plus.v1.yifu.social.vo.TSocialInfoVo;
import com.yifu.cloud.plus.v1.yifu.social.vo.TSocialSoldierReturnErrorVo;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 社保士兵
 *
 * @author hgw
 * @date 2024-5-8 14:55:36
 */
@AllArgsConstructor
@Log4j2
@Service
public class TSocialSoldierServiceImpl extends ServiceImpl<TSocialInfoMapper, TSocialInfo> implements TSocialSoldierService {

	private RestTemplate restTemplate = new RestTemplate();
	private final SocialConfig socialConfig;
	private final TDispatchInfoService tDispatchInfoService;

	@Override
	public R<String> getOneAppGetModuleDetail() {
		/*Map<String, String> moduleDetailMap = socialConfig.getOneModuleDetailMap(restTemplate);
		if (moduleDetailMap != null && !moduleDetailMap.isEmpty() && moduleDetailMap.get("社保增员") != null) {
			String terminalId = socialConfig.getTwoTerminalId(restTemplate, moduleDetailMap.get("社保增员"));
			if (Common.isNotNull(terminalId)) {
				// TODO-需要重写导出sql
				MultipartFile file = this.getFile();
				String fileUrl = socialConfig.getThreeTerminalId(restTemplate, file);
				System.out.println(fileUrl);
				String addId = socialConfig.getFourAppAdd(restTemplate, fileUrl, moduleDetailMap.get("社保增员"), terminalId);
				System.out.println(addId);
				R<String> resultFile = socialConfig.getFiveJob(restTemplate, addId);
				System.out.println("resultFile="+resultFile);
			}
		}*/
		R<String> resultFile = socialConfig.getFiveJob(restTemplate, "9");
		System.out.println("resultFile="+resultFile);
		HttpURLConnection conn = null;
		try {

			// 解决中文文件名的乱码问题
			String fileUrl = resultFile.getData();
			String dowloadUrl = fileUrl;
			int indexOf = fileUrl.lastIndexOf("/")+1;
			fileUrl = fileUrl.substring(indexOf);
			try {
				fileUrl = URLEncoder.encode(fileUrl, "UTF-8");
			} catch (UnsupportedEncodingException e) {
				log.info("编码异常！");
			}
			dowloadUrl = dowloadUrl.substring(0,indexOf) + fileUrl;

			URL url = new URL(dowloadUrl);
			conn = (HttpURLConnection) url.openConnection();
			//设置超时间为30秒
			conn.setConnectTimeout(30 * 1000);
			InputStream in = conn.getInputStream();

			importDiy(in);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return R.ok();
	}

	public MultipartFile getFile() {
		File file = null;
		SocialHandleSearchVo searchVo = new SocialHandleSearchVo();
		searchVo.setEmpIdcard("340103196311171019");
		searchVo.setLimitStart(0);
		//searchVo.setLimitEnd(CommonConstants.EXCEL_EXPORT_LIMIT);
		searchVo.setLimitEnd(1);
		// TODO-需要重写导出sql
		List<SocialHandleExportVo> list = tDispatchInfoService.getRecordRosterList(searchVo, null);
		if (list != null) {
			System.out.println(list.get(0).getEmpIdcard() + list.get(0).getPensionStart());
			String filePath = "socialFile" + DateUtil.getThisTime();
			EasyExcelFactory.write(filePath, TSalaryAccountExportByEkpVo.class).sheet("社保明细").doWrite(list);
			file = new File(filePath);
		}
		if (file != null) {
			return getMultipartFile(file);
		}
		return null;
	}

	public static MultipartFile getMultipartFile(File file) {
		FileItem item = new DiskFileItemFactory().createItem("file", MediaType.MULTIPART_FORM_DATA_VALUE, true, file.getName());
		try (InputStream input = new FileInputStream(file); OutputStream os = item.getOutputStream()) {
			// 流转移
			IOUtils.copy(input, os);
		} catch (Exception e) {
			throw new IllegalArgumentException("Invalid file: " + e, e);
		}
		return new CommonsMultipartFile(item);
	}

	public R<List<ErrorMessage>> importDiy(InputStream inputStream) {
		List<ErrorMessage> errorMessageList = new ArrayList<>();
		ExcelUtil<TSocialSoldierReturnErrorVo> util1 = new ExcelUtil<>(TSocialSoldierReturnErrorVo.class);
		// 写法2：
		// 匿名内部类 不用额外写一个DemoDataListener
		// 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
		try {
			EasyExcel.read(inputStream, TSocialSoldierReturnErrorVo.class, new ReadListener<TSocialSoldierReturnErrorVo>() {
				/**
				 * 单次缓存的数据量
				 */
				public static final int BATCH_COUNT = CommonConstants.BATCH_COUNT;
				/**
				 *临时存储
				 */
				private List<TSocialSoldierReturnErrorVo> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

				@Override
				public void invoke(TSocialSoldierReturnErrorVo data, AnalysisContext context) {
					ReadRowHolder readRowHolder = context.readRowHolder();
					Integer rowIndex = readRowHolder.getRowIndex();
					data.setRowIndex(rowIndex+1);
					ErrorMessage errorMessage = util1.checkEntity(data, data.getRowIndex());
					if (Common.isNotNull(errorMessage)){
						errorMessageList.add(errorMessage);
					}else {
						cachedDataList.add(data);
					}
					if (cachedDataList.size() >= BATCH_COUNT) {
						saveData();
						// 存储完成清理 list
						cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
					}
				}
				@Override
				public void doAfterAllAnalysed(AnalysisContext context) {
					saveData();
				}

				/**
				 * 加上存储数据库
				 */
				private void saveData() {
					log.info("{}条数据，开始存储数据库！", cachedDataList.size());
					importTSocialInfo(cachedDataList,errorMessageList);
					log.info("存储数据库成功！");
				}
			}).sheet().doRead();
		}catch (Exception e){
			log.error(CommonConstants.IMPORT_DATA_ANALYSIS_ERROR,e);
			return R.failed(CommonConstants.IMPORT_DATA_ANALYSIS_ERROR);
		}
		return  R.ok(errorMessageList);
	}

	private void importTSocialInfo(List<TSocialSoldierReturnErrorVo> excelVOList, List<ErrorMessage> errorMessageList) {
		// 个性化校验逻辑
		// 执行数据插入操作 组装
		TSocialSoldierReturnErrorVo excel;
		for (int i = 0; i < excelVOList.size(); i++) {
			excel = excelVOList.get(i);
			// 插入
			System.out.println(excel.getErrorInfo());
			errorMessageList.add(new ErrorMessage(excel.getRowIndex(),CommonConstants.SAVE_SUCCESS));
		}
	}

}
