package com.jpsoft.shinestar.modules.base.controller;

import com.github.pagehelper.Page;
import com.jpsoft.shinestar.config.OSSConfig;
import com.jpsoft.shinestar.modules.base.entity.CompanyInfo;
import com.jpsoft.shinestar.modules.base.entity.CompanyPaymentInfo;
import com.jpsoft.shinestar.modules.base.entity.PersonInfo;
import com.jpsoft.shinestar.modules.base.service.CompanyInfoService;
import com.jpsoft.shinestar.modules.base.service.PersonInfoService;
import com.jpsoft.shinestar.modules.common.utils.OSSUtil;
import com.jpsoft.shinestar.modules.common.utils.POIUtils;
import com.jpsoft.shinestar.modules.common.utils.PojoUtils;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import com.jpsoft.shinestar.modules.common.dto.MessageResult;
import com.jpsoft.shinestar.modules.base.entity.CheckinInfo;
import com.jpsoft.shinestar.modules.base.service.CheckinInfoService;
import com.jpsoft.shinestar.modules.sys.entity.User;
import com.jpsoft.shinestar.modules.sys.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

import java.io.*;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/base/checkinInfo")
@Api(description = "租户管理")
public class CheckinInfoController {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private OSSConfig ossConfig;
    @Autowired
    private CheckinInfoService checkinInfoService;
    @Autowired
    private PersonInfoService personInfoService;
    @Autowired
    private CompanyInfoService companyInfoService;
    @Autowired
    private UserService userService;

    @ApiOperation(value="创建空记录")
    @GetMapping("create")
    public MessageResult<CheckinInfo> create(){
        MessageResult<CheckinInfo> msgResult = new MessageResult<>();

        CheckinInfo checkinInfo = new CheckinInfo();

        msgResult.setData(checkinInfo);
        msgResult.setResult(true);

        return msgResult;
    }
    
    @ApiOperation(value="添加信息")
    @PostMapping("add")
    public MessageResult<CheckinInfo> add(@RequestBody CheckinInfo checkinInfo,@RequestAttribute String subject){
        MessageResult<CheckinInfo> msgResult = new MessageResult<>();

        try {
            User user = userService.get(subject);

            checkinInfo.setId(UUID.randomUUID().toString());
            checkinInfo.setPropertyId(user.getCompanyId());
            checkinInfo.setWechatPay(false);
            checkinInfo.setAliPay(false);
            checkinInfo.setDelFlag(false);
            checkinInfo.setCreateBy(subject);
            checkinInfo.setCreateTime(new Date());
            if(StringUtils.isNotEmpty(checkinInfo.getArea())){
                try {
                    BigDecimal decimal = new BigDecimal(checkinInfo.getArea());
                    checkinInfo.setArea(decimal.setScale(2, RoundingMode.HALF_UP).toString());
                } catch (Exception ex) {

                }
            }

            PersonInfo personInfo = personInfoService.get(checkinInfo.getArtificialPerson());
            if(personInfo != null) {
                checkinInfo.setArtificialPersonPhone(personInfo.getPhone());
            }

            int affectCount = checkinInfoService.insert(checkinInfo);

            if (affectCount > 0) {
                msgResult.setResult(true);
                msgResult.setData(checkinInfo);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("数据库添加失败");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value="获取信息")
    @GetMapping("edit/{id}")
    public MessageResult<CheckinInfo> edit(@PathVariable("id") String id){
        MessageResult<CheckinInfo> msgResult = new MessageResult<>();

        try {
            CheckinInfo checkinInfo = checkinInfoService.get(id);

            if (checkinInfo != null) {
                msgResult.setResult(true);
                msgResult.setData(checkinInfo);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("数据库不存在该记录!");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value="更新用户")
    @PostMapping("update")
    public MessageResult<CheckinInfo> update(@RequestBody CheckinInfo checkinInfo,@RequestAttribute String subject){
        MessageResult<CheckinInfo> msgResult = new MessageResult<>();

        try {
            checkinInfo.setUpdateBy(subject);
            checkinInfo.setUpdateTime(new Date());

            PersonInfo personInfo = personInfoService.get(checkinInfo.getArtificialPerson());
            if(personInfo != null) {
                checkinInfo.setArtificialPersonPhone(personInfo.getPhone());
            }
            if(StringUtils.isNotEmpty(checkinInfo.getArea())){
                try {
                    BigDecimal decimal = new BigDecimal(checkinInfo.getArea());
                    checkinInfo.setArea(decimal.setScale(2, RoundingMode.HALF_UP).toString());
                } catch (Exception ex) {

                }
            }

            int affectCount = checkinInfoService.update(checkinInfo);

            if (affectCount > 0) {
                msgResult.setResult(true);
                msgResult.setData(checkinInfo);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("数据库更新失败");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

	@ApiOperation(value="删除")
    @PostMapping("delete/{id}")
    public MessageResult<Integer> delete(@PathVariable("id") String id,@RequestAttribute String subject){
        MessageResult<Integer> msgResult = new MessageResult<>();

        try {
            CheckinInfo checkinInfo = checkinInfoService.get(id);
            checkinInfo.setDelFlag(true);
            checkinInfo.setUpdateBy(subject);
            checkinInfo.setUpdateTime(new Date());

            int affectCount = checkinInfoService.update(checkinInfo);

            if (affectCount > 0) {
                msgResult.setResult(true);
                msgResult.setData(affectCount);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("删除失败");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }


    @ApiOperation(value="批量删除")
    @PostMapping("batchDelete")
    public MessageResult<Integer> batchDelete(@RequestBody List<String> idList,@RequestAttribute String subject){
        MessageResult<Integer> msgResult = new MessageResult<>();

        try {
            int affectCount = 0;

            for (String id : idList) {
                CheckinInfo checkinInfo = checkinInfoService.get(id);
                checkinInfo.setDelFlag(true);
                checkinInfo.setUpdateBy(subject);
                checkinInfo.setUpdateTime(new Date());

                affectCount += checkinInfoService.update(checkinInfo);
            }

            if (affectCount > 0) {
                msgResult.setResult(true);
                msgResult.setData(affectCount);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("删除失败");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value="列表")
    @RequestMapping(value = "pageList",method = RequestMethod.POST)
    public MessageResult<Map> pageList(
            String building, String name, String feeExpirationTime, String contractExpirationTime,
            @RequestParam(value="pageIndex",defaultValue="1") int pageIndex,
            @RequestParam(value="pageSize",defaultValue="20") int pageSize,
            @RequestAttribute String subject){

        //当前用户ID
        System.out.println(subject);

        MessageResult<Map> msgResult = new MessageResult<>();

        User user = userService.get(subject);

        Map<String,Object> searchParams = new HashMap<>();
        searchParams.put("propertyId",user.getCompanyId());

        List<Sort> sortList = new ArrayList<>();
        sortList.add(new Sort("a.building_","asc"));
        sortList.add(new Sort("a.room_","asc"));

        if (StringUtils.isNotEmpty(building)) {
            searchParams.put("building","%" + building + "%");
        }
        if (StringUtils.isNotEmpty(name)) {
            searchParams.put("name","%" + name + "%");
        }
        if (StringUtils.isNotEmpty(feeExpirationTime)) {
            searchParams.put("feeExpirationTime",feeExpirationTime);
        }
        if (StringUtils.isNotEmpty(contractExpirationTime)) {
            searchParams.put("contractExpirationTime",contractExpirationTime);
        }

        Page<CheckinInfo> page = checkinInfoService.pageSearch(searchParams,pageIndex,pageSize,true,sortList);
        for(CheckinInfo checkinInfo : page.getResult()){
            CompanyInfo companyInfo = companyInfoService.get(checkinInfo.getCompanyId());

            if(companyInfo != null) {
                checkinInfo.setCompanyName(companyInfo.getName());
            }

            PersonInfo personInfo = personInfoService.get(Long.valueOf(checkinInfo.getArtificialPerson()));

            if(personInfo != null) {
                checkinInfo.setArtificialPersonN(personInfo.getName());
            }
        }

        msgResult.setResult(true);
        msgResult.setData(PojoUtils.pageWrapper(page));

        return msgResult;
    }

    @ApiOperation(value="修改是否支持微信支付宝支付")
    @PostMapping("updateWechatPayOrAliPay")
    public MessageResult<Integer> updateWechatPayOrAliPay(String id,Boolean wechatPay,Boolean aliPay, @RequestAttribute String subject) {
        MessageResult<Integer> msgResult = new MessageResult<>();

        try {
            CheckinInfo checkinInfo = checkinInfoService.get(id);

            if(checkinInfo!=null){
                if(wechatPay!=null) {
                    checkinInfo.setWechatPay(wechatPay);
                }
                if(aliPay!=null) {
                    checkinInfo.setAliPay(aliPay);
                }

                checkinInfo.setUpdateBy(subject);
                checkinInfo.setUpdateTime(new Date());

                int count = checkinInfoService.update(checkinInfo);

                msgResult.setResult(true);
                msgResult.setData(count);
            }
            else{
                msgResult.setResult(false);
                msgResult.setMessage("更新失败");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value="导入租户")
    @PostMapping("importXls")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uploadFile",value = "上传文件", required = true,paramType="form", dataType = "__file")
    })
    public MessageResult<String> importXls(MultipartFile uploadFile,
                                           @RequestAttribute String subject){
        User user = userService.get(subject);
        MessageResult<String> msgResult = new MessageResult<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        try {
            POIUtils poiUtils = new POIUtils(uploadFile.getInputStream());
            int sheetIndex = 0;
            Sheet sheet1 = poiUtils.getSheetAt(sheetIndex);

            String[] colNames = new String[]{"楼栋","房号","企业名称","法人","联系人","面积","入驻时间","费用到期时间","合同到期时间","租赁期限"};
            Map<String,Integer> headerMap = new HashMap<>();

            Row headerRow = sheet1.getRow(0);
            for (int i=0;i<colNames.length;i++) {
                String colName = colNames[i];
                for (int j = 0; j < headerRow.getLastCellNum(); j++) {
                    String title = headerRow.getCell(j).getStringCellValue();
                    if (title.indexOf(colName)!=-1){
                        headerMap.put(colName, j);
                        break;
                    }
                }
            }

            int affectCount = 0;
            int failCount = 0;
            int validateColIndex = 13;
            for(int rowIndex=1 ; rowIndex<=sheet1.getLastRowNum(); rowIndex++){
                try {
                    CheckinInfo checkinInfo = new CheckinInfo();

                    String building = "";
                    if(headerMap.containsKey("楼栋")) {
                        building = poiUtils.getCellValue(sheetIndex, rowIndex, headerMap.get("楼栋")).toString().replace(" ", "");
                        checkinInfo.setBuilding(building);
                    }

                    String room = "";
                    if(headerMap.containsKey("房号")) {
                        room = poiUtils.getCellValue(sheetIndex, rowIndex, headerMap.get("房号")).toString().replace(" ", "");
                        checkinInfo.setRoom(room);
                    }

                    String companyId = "";
                    if(headerMap.containsKey("企业名称")) {
                        companyId = poiUtils.getCellValue(sheetIndex, rowIndex, headerMap.get("企业名称")).toString().replace(" ", "");
                        CompanyInfo companyInfo = companyInfoService.findByName(companyId);
                        if(companyInfo != null){
                            companyId = companyInfo.getId();
                            checkinInfo.setCompanyId(companyId);
                        }
                        else{
                            sheet1.getRow(rowIndex).createCell(validateColIndex).setCellValue("该企业名称在系统中不存在!");
                            failCount++;
                            continue;
                        }
                    }

                    String boss = "";
                    if(headerMap.containsKey("法人")) {
                        boss = poiUtils.getCellValue(sheetIndex, rowIndex, headerMap.get("法人")).toString().replace(" ", "");
                        checkinInfo.setBoss(boss);
                    }

                    String artificialPerson = "";
                    if(headerMap.containsKey("联系人")) {
                        Boolean bl = false;
                        artificialPerson = poiUtils.getCellValue(sheetIndex, rowIndex, headerMap.get("联系人")).toString().replace(" ", "");
                        List<PersonInfo> list = personInfoService.findByCompanyId(companyId);
                        for(PersonInfo personInfo : list) {
                            if(artificialPerson.equals(personInfo.getName())){
                                checkinInfo.setArtificialPerson(personInfo.getId());
                                checkinInfo.setArtificialPersonPhone(personInfo.getPhone());
                                bl = true;
                            }
                        }
                        if(bl == false){
                            sheet1.getRow(rowIndex).createCell(validateColIndex).setCellValue("该联系人在系统中不存在!");
                            failCount++;
                            continue;
                        }
                    }

                    String area = "";
                    if(headerMap.containsKey("面积")) {
                        area = poiUtils.getCellValue(sheetIndex, rowIndex, headerMap.get("面积")).toString().replace(" ", "");
                        if(StringUtils.isNotEmpty(area)) {
                            try {
                                BigDecimal decimal = new BigDecimal(area);
                                checkinInfo.setArea(decimal.setScale(2, RoundingMode.HALF_UP).toString());
                            } catch (Exception ex) {
                                sheet1.getRow(rowIndex).createCell(validateColIndex).setCellValue("面积格式有误!");
                                failCount++;
                                continue;
                            }
                        }
                    }

                    String checkinTime = "";
                    if(headerMap.containsKey("入驻时间")) {
                        checkinTime = poiUtils.getCellValue(sheetIndex, rowIndex, headerMap.get("入驻时间")).toString().replace(" ", "");
                        if(StringUtils.isNotEmpty(checkinTime)) {
                            try {
                                checkinInfo.setCheckinTime(sdf.parse(checkinTime));
                            } catch (Exception ex) {
                                sheet1.getRow(rowIndex).createCell(validateColIndex).setCellValue("入驻时间格式有误!");
                                failCount++;
                                continue;
                            }
                        }
                    }

                    String feeExpirationTime = "";
                    if(headerMap.containsKey("费用到期时间")) {
                        feeExpirationTime = poiUtils.getCellValue(sheetIndex, rowIndex, headerMap.get("费用到期时间")).toString().replace(" ", "");
                        if(StringUtils.isNotEmpty(feeExpirationTime)) {
                            try {
                                checkinInfo.setFeeExpirationTime(sdf.parse(feeExpirationTime));
                            } catch (Exception ex) {
                                sheet1.getRow(rowIndex).createCell(validateColIndex).setCellValue("费用到期时间格式有误!");
                                failCount++;
                                continue;
                            }
                        }
                    }

                    String contractExpirationTime = "";
                    if(headerMap.containsKey("合同到期时间")) {
                        contractExpirationTime = poiUtils.getCellValue(sheetIndex, rowIndex, headerMap.get("合同到期时间")).toString().replace(" ", "");
                        if(StringUtils.isNotEmpty(contractExpirationTime)) {
                            try {
                                checkinInfo.setContractExpirationTime(sdf.parse(contractExpirationTime));
                            } catch (Exception ex) {
                                sheet1.getRow(rowIndex).createCell(validateColIndex).setCellValue("合同到期时间格式有误!");
                                failCount++;
                                continue;
                            }
                        }
                    }

                    String leaseTerm = "";
                    if(headerMap.containsKey("租赁期限")) {
                        leaseTerm = poiUtils.getCellValue(sheetIndex, rowIndex, headerMap.get("租赁期限")).toString().replace(" ", "");
                        checkinInfo.setLeaseTerm(leaseTerm);
                    }

                    checkinInfo.setId(UUID.randomUUID().toString());
                    checkinInfo.setPropertyId(user.getCompanyId());
                    checkinInfo.setWechatPay(false);
                    checkinInfo.setAliPay(false);
                    checkinInfo.setDelFlag(false);
                    checkinInfo.setCreateBy(subject);
                    checkinInfo.setCreateTime(new Date());
                    checkinInfoService.insert(checkinInfo);
                    affectCount++;
                }
                catch(Exception innerEx){
                    logger.error(innerEx.getMessage(),innerEx);
                }
            }

            if (failCount>0){
                //有导入失败的记录
                msgResult.setResult(false);
                msgResult.setMessage("数据成功导入" + affectCount + "条,有" + failCount + "条数据未导入成功，错误原因请查看报表。");

                //todo 只保留错误数据的sheet
                Workbook wb = poiUtils.exportErrorXls(sheetIndex,validateColIndex,1 + affectCount + failCount);

                //todo 将wb保存到oss
                ByteArrayOutputStream output = new ByteArrayOutputStream();
                wb.write(output);

                byte[] buffer = output.toByteArray();
                ByteArrayInputStream input = new ByteArrayInputStream(buffer);

                String downloadUrl = OSSUtil.upload(ossConfig,"import","error.xls",input);

                //todo 返回导入失败报表下载链接
                msgResult.setData(downloadUrl);
            }
            else{
                msgResult.setResult(true);
                msgResult.setMessage("数据成功导入" + affectCount + "条");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }
}
