package com.app.ydl.marketing.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.poi.excel.WorkbookUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.app.framework.core.support.controller.CrudBaseControllerSupport;
import com.app.framework.core.support.view.form.AjaxResult;
import com.app.framework.core.support.view.grid.ExGridLoad;
import com.app.framework.core.support.view.grid.Paging;
import com.app.ydl.marketing.model.LandingChannelConfigExtend;
import com.app.ydl.marketing.service.LandingChannelConfigExtendService;
import com.app.ydl.marketing.service.LandingChannelWxmpAccessRecordService;
import com.app.ydl.marketing.view.LandingChannelConfigExtendView;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.util.*;
import java.util.stream.Collectors;

@Controller
@RequestMapping("/marketing")
public class LandingChannelConfigExtendController extends CrudBaseControllerSupport<LandingChannelConfigExtendView> {

    @Value("${ydl.marketing.updateConfigExtend}")
    private String updateConfigExtendUrl;

    @Value("${ydl.marketing.updateWxmpAccessRecord}")
    private String updateWxmpAccessRecordUrl;

    @Value("${ydl.marketing.listLandingChannel}")
    private String listLandingChannelUrl;

    @Resource
    LandingChannelConfigExtendService landingChannelConfigExtendService;

    @Resource
    LandingChannelWxmpAccessRecordService landingChannelWxmpAccessRecordService;

    private JSONArray landingChannelList;

    private List<String> buildFfrom(String ffrom) {
        List<String> ffromList = new ArrayList<>();
        if (StringUtils.isNotBlank(ffrom)) {
            ffromList.add(ffrom);
        } else {
            ffromList.add("yj_listeners_douyin");
            ffromList.add("yj_listeners_tengxun");
        }
        return ffromList;
    }

    private JSONArray listLandingChannel() {
        try {
            String s = HttpUtil.get(listLandingChannelUrl);
            JSONObject object = JSONObject.parseObject(s);
            return object.getJSONArray("data");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 查询列表的具体实现
     * 请求：list
     *
     * @param request HttpServletRequest
     * @param view    查询条件
     * @param paging  分页条件
     * @return 查询结果
     */
    @Override
    public List<LandingChannelConfigExtendView> list(HttpServletRequest request, LandingChannelConfigExtendView view, Paging paging) {
        Map<Long, String> map = landingChannelList.stream().filter(Objects::nonNull)
                .collect(Collectors.toMap(
                        object -> {
                            JSONObject item = (JSONObject) object;
                            return item.getLong("channelConfigId");
                        },
                        object -> {
                            JSONObject item = (JSONObject) object;
                            return item.getString("name");
                        }
                ));

        List<LandingChannelConfigExtend> list = landingChannelConfigExtendService.list(view);
        return list.stream().map(e -> {
            LandingChannelConfigExtendView v = new LandingChannelConfigExtendView();
            BeanUtils.copyProperties(e, v);
            v.setChannelConfigName(map.get(v.getChannelConfigId()));
            return v;
        }).collect(Collectors.toList());
    }

    /**
     * 保存记录的具体实现
     * 请求：saveEntity
     *
     * @param request HttpServletRequest
     * @param entity  实体
     * @return 影响结果数
     */
    @Override
    public AjaxResult saveEntity(HttpServletRequest request, LandingChannelConfigExtendView entity) {
        return AjaxResult.wrap(false);
    }

    /**
     * 删除记录,根据Id 具体实现
     * 请求：deleteById 参数oid
     * 请求：batchDelete 参数oid数组
     *
     * @param request HttpServletRequest
     * @param oids    实体
     * @return 影响结果数
     */
    @Override
    public AjaxResult batchDelete(HttpServletRequest request, Long oids[]) {
        return AjaxResult.wrap(false);
    }

    @RequestMapping(value = "/info")
    public ModelAndView info(HttpServletRequest request, String ffrom) {
        LandingChannelConfigExtend configExtend = landingChannelConfigExtendService.getByFfrom(ffrom);
        Map<String, Object> result = new HashMap<>();
        result.put("entity", configExtend);
        return new ModelAndView("admin/business/marketing/info.html", result);
    }

    @RequestMapping(value = "/toEditInfo")
    public ModelAndView toEditInfo(HttpServletRequest request, String ffrom, Long channelConfigId) {
        Map<String, Object> result = new HashMap<String, Object>();

        if (StringUtils.isNotBlank(ffrom)) {
            LandingChannelConfigExtend configExtend = landingChannelConfigExtendService.getByFfrom(ffrom);
            result.put("entity", configExtend);
        }

        result.put("updateConfigExtendUrl", updateConfigExtendUrl);
        result.put("listLandingChannel", landingChannelList);
        result.put("channelConfigId", channelConfigId);
        return new ModelAndView("admin/business/marketing/edit_info.html", result);
    }

    @RequestMapping(value = "/toEdit")
    public ModelAndView toEdit(HttpServletRequest request, String ffrom, Long channelConfigId) {
        LandingChannelConfigExtend configExtend = landingChannelConfigExtendService.getByFfrom(ffrom);
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("entity", configExtend);
        result.put("updateConfigExtendUrl", updateConfigExtendUrl);
        result.put("channelConfigId", channelConfigId);
        return new ModelAndView("admin/business/marketing/edit.html", result);
    }

    @RequestMapping(value = "/golist")
    public ModelAndView golist(HttpServletRequest request, Long channelConfigId) {
        landingChannelList = this.listLandingChannel();
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("listLandingChannel", landingChannelList);
        result.put("channelConfigId", channelConfigId);
        return new ModelAndView("admin/business/marketing/list.html", result);
    }


    @RequestMapping(value = "/joinWxcorp/golist")
    public ModelAndView goJoinWxcorpList(String ffrom, Long channelConfigId) {
        LandingChannelConfigExtend configExtend = landingChannelConfigExtendService.getByFfrom(ffrom);
        String startDate = DateUtil.formatDate(new Date());
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("entity", configExtend);
        result.put("startDate", startDate);
        result.put("endDate", startDate);
        result.put("channelConfigId", channelConfigId);
        return new ModelAndView("admin/business/marketing/list_join_wxcorp.html", result);
    }

    /**
     * 查询加V用户列表
     */
    @RequestMapping(value = "/joinWxcorp/list")
    @ResponseBody
    public ExGridLoad selectJoinWxcorpList(String ffrom, String startDate, String endDate, Paging paging) {
        if (StringUtils.isBlank(startDate)) {
            startDate = DateUtil.formatDate(new Date());
        }
        if (StringUtils.isBlank(endDate)) {
            endDate = DateUtil.formatDate(new Date());
        }
        String startTime = startDate + " 00:00:00", endTime = endDate + " 23:59:59";
        List<String> ffromList = this.buildFfrom(ffrom);
        List<Map<String, Object>> list = landingChannelWxmpAccessRecordService.selectJoinWxcorpList(ffromList, startTime, endTime, paging);
        return ExGridLoad.wrapExGridLoad(list, paging);
    }

    @RequestMapping(value = "/joinWxcorp/export")
    public void export(HttpServletResponse response, String ffrom, String startDate, String endDate) throws Exception {
        if (StringUtils.isBlank(startDate)) {
            startDate = DateUtil.formatDate(new Date());
        }
        if (StringUtils.isBlank(endDate)) {
            endDate = DateUtil.formatDate(new Date());
        }
        String filename = String.format("加V数据(%s-%s).xlsx", startDate, endDate);
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/x-msdownload");
        response.setHeader("Content-disposition", "attachment; filename=" + new String(filename.getBytes("utf-8"), "ISO8859-1"));

        String sheetName = "SheetName";
        String header[] = new String[]{"企微成员userid", "用户uid", "用户手机号", "付款时间", "订单号", "渠道"};
        List<String[]> dataList = new ArrayList<>();

        List<String> ffromList = this.buildFfrom(ffrom);
        String startTime = startDate + " 00:00:00", endTime = endDate + " 23:59:59";
        List<Map<String, Object>> list = landingChannelWxmpAccessRecordService.selectJoinWxcorpList(ffromList, startTime, endTime, null);

        for (Map<String, Object> map : list) {
            dataList.add(new String[]{
                    MapUtils.getString(map, "join_wxcorp_userid"),
                    MapUtils.getString(map, "uid"),
                    MapUtils.getString(map, "phone"),
                    MapUtils.getString(map, "pay_time"),
                    MapUtils.getString(map, "id"),
                    MapUtils.getString(map, "from")
            });
        }

        ByteArrayOutputStream stream = this.writeExcelData(sheetName, header, dataList);
        stream.writeTo(response.getOutputStream());
    }


    @RequestMapping(value = "/unJoinWxcorp/golist")
    public ModelAndView goSelectUnJoinWxcorpList(String ffrom, Long channelConfigId) {
        LandingChannelConfigExtend configExtend = landingChannelConfigExtendService.getByFfrom(ffrom);
        String startDate = DateUtil.formatDate(new Date());
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("entity", configExtend);
        result.put("startDate", startDate);
        result.put("endDate", startDate);
        result.put("channelConfigId", channelConfigId);
        result.put("updateWxmpAccessRecordUrl", updateWxmpAccessRecordUrl);
        return new ModelAndView("admin/business/marketing/list_unjoin_wxcorp.html", result);
    }

    /**
     * 查询付费未加V用户列表
     */
    @RequestMapping(value = "/unJoinWxcorp/list")
    @ResponseBody
    public ExGridLoad selectUnJoinWxcorpList(String ffrom, String startDate, String endDate, Paging paging) {
        if (StringUtils.isBlank(startDate)) {
            startDate = DateUtil.formatDate(new Date());
        }
        if (StringUtils.isBlank(endDate)) {
            endDate = DateUtil.formatDate(new Date());
        }
        List<String> ffromList = this.buildFfrom(ffrom);
        String startTime = startDate + " 00:00:00", endTime = endDate + " 23:59:59";

        List<Map<String, Object>> list = landingChannelWxmpAccessRecordService.selectUnJoinWxcorpList(ffromList, startTime, endTime, paging);
        return ExGridLoad.wrapExGridLoad(list, paging);
    }

    @RequestMapping(value = "/unJoinWxcorp/export")
    public void exportUnJoinWxcorpList(HttpServletResponse response, String ffrom, String startDate, String endDate) throws Exception {
        if (StringUtils.isBlank(startDate)) {
            startDate = DateUtil.formatDate(new Date());
        }
        if (StringUtils.isBlank(endDate)) {
            endDate = DateUtil.formatDate(new Date());
        }
        String filename = String.format("付费未加V数据(%s-%s).xlsx", startDate, endDate);
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/x-msdownload");
        response.setHeader("Content-disposition", "attachment; filename=" + new String(filename.getBytes("utf-8"), "ISO8859-1"));

        String sheetName = "SheetName";
        String header[] = new String[]{"用户uid", "用户手机号", "付款时间", "订单号", "渠道"};
        List<String[]> dataList = new ArrayList<>();

        List<String> ffromList = this.buildFfrom(ffrom);
        String startTime = startDate + " 00:00:00", endTime = endDate + " 23:59:59";
        List<Map<String, Object>> list = landingChannelWxmpAccessRecordService.selectUnJoinWxcorpList(ffromList, startTime, endTime, null);

        for (Map<String, Object> map : list) {
            dataList.add(new String[]{
                    map.get("uid").toString(),
                    map.get("phone").toString(),
                    map.get("pay_time").toString(),
                    map.get("id").toString(),
                    map.get("from").toString()
            });
        }

        ByteArrayOutputStream stream = this.writeExcelData(sheetName, header, dataList);
        stream.writeTo(response.getOutputStream());
    }

    /**
     * 生成短链接
     */
    @RequestMapping(value = "/wxa/generateUrlink")
    @ResponseBody
    public AjaxResult generateUrlink(String ffrom, Integer at) {
        if (at == null) at = 0;
        String url = String.format("https://static.yidianling.com/%s/index.html?ffrom=%s", "dev".equals(SpringUtil.getActiveProfile()) ? "course_dev" : "course", ffrom);
        Map<String, Object> bodyData = new HashMap<>();
        bodyData.put("url", url);
        if (at.equals(3)) {
            bodyData.put("expiry", DateUtil.formatDate(DateUtil.offsetMonth(new Date(), 3)));
        } else if (at.equals(6)) {
            bodyData.put("expiry", DateUtil.formatDate(DateUtil.offsetMonth(new Date(), 6)));
        }

        try {
            HttpRequest post = HttpUtil.createPost("https://www.urlc.cn/api/url/add");
            post.header("Content-Type", "application/json");
            post.header("Authorization", "Token NZRaipIJ9TL1iKEZe5kB");
            post.body(JSON.toJSONString(bodyData));
            HttpResponse response = post.execute();
            JSONObject object = JSONObject.parseObject(response.body());
            if (object.getString("error").equals("1")) {
                return AjaxResult.wrapError(object.getString("msg"));
            }
            Map<String, String> respDto = new HashMap<>();
            respDto.put("shortUrl", object.getString("short"));
            return AjaxResult.wrap(true, null, respDto);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return AjaxResult.wrapError("生成失败");

    }

    private ByteArrayOutputStream writeExcelData(String sheetName, String header[], List<String[]> dataList) throws Exception {
        if (StringUtils.isBlank(sheetName)) {
            sheetName = "Sheet1";
        }
        Workbook workbook = WorkbookUtil.createBook(true);
        Sheet sheet = workbook.createSheet(sheetName);

        //创建表头行
        int headerRow = 0;
        if (header != null) {
            headerRow = 1;

            CellStyle cellStyle = workbook.createCellStyle();
            cellStyle.setAlignment(HorizontalAlignment.CENTER);
            cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

            Row title = sheet.createRow(0);
            for (int i = 0; i < header.length; i++) {
                Cell cell = title.createCell(i);
                cell.setCellValue(header[i]);
                cell.setCellStyle(cellStyle);
            }
        }

        //追加数据
        int size = dataList != null ? dataList.size() : 0;
        for (int i = 0; i < size; i++) {
            Row nextrow = sheet.createRow(i + headerRow);
            String[] data = dataList.get(i);
            for (int j = 0; j < data.length; j++) {
                Cell cell2 = nextrow.createCell(j);
                cell2.setCellValue(data[j]);
            }
        }

        //将表格写入ByteArrayOutputStream
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        workbook.write(stream);
        stream.close();
        return stream;
    }
}
