package com.org.hktshop.service.System;

import com.aliyun.oss.OSSClient;
import com.org.hktshop.Interface.system.IHktNewsArticleService;
import com.org.hktshop.Interface.system.IHktNewsCategoryService;
import com.org.hktshop.base.BaseService;
import com.org.hktshop.base.MongoHelper;
import com.org.hktshop.entity.Page;
import com.org.hktshop.entity.admin.HktAdmin;
import com.org.hktshop.entity.system.HktNewsArticle;
import com.org.hktshop.entity.system.HktNewsCategory;
import com.org.hktshop.entity.vo.HktUrlLinkVo;
import com.org.hktshop.properties.AliyunOSSProperties;
import com.org.hktshop.service.aliyun.AliyunOssService;
import com.org.hktshop.utils.DateUtil;
import com.org.hktshop.utils.ExecSqlLib;
import com.org.hktshop.utils.Ret;
import com.org.hktshop.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class HktNewsArticleServiceImpl extends BaseService<HktNewsArticle> implements IHktNewsArticleService {

    @Autowired
    private MongoHelper mongoHelper;

    @Autowired
    MongoHelper<HktNewsCategory> categoryMongoHelper;

    @Autowired
    private IHktNewsCategoryService categoryService;

    @Autowired
    private AliyunOSSProperties aliyunOSSProperties;

    @Autowired
    private AliyunOssService aliyunOssService;

    @Override
    public void InitData() {
        List<HktNewsArticle> list = mongoHelper.find(new HktNewsArticle(), HktNewsArticle.class);

        if (list.isEmpty()) {
            list = queryList(new HktNewsArticle());
            for (HktNewsArticle article : list) {
                mongoHelper.save(article);
            }
        }
    }

    @Override
    public void updateNewNum(HktNewsArticle newsArticle) {
        try {
            HktNewsArticle article = new HktNewsArticle();
            article.setId(newsArticle.getId());
            article.setHit(newsArticle.getHit());
            if (this.updateJdbc(article)) {
                //MongoDB更新
                mongoHelper.mongoUpdate(newsArticle.getId(), article, HktNewsArticle.class);
            }
        } catch (Exception ex) {
        }
    }

    @Override
    public Ret updateArticle(HktAdmin admin, HktNewsArticle hktNewsArticle) throws UnsupportedEncodingException {
        Ret ret = Ret.create();
        hktNewsArticle.setUserId(admin.getId());

        if (StringUtils.isNull(hktNewsArticle.getId())) {
            hktNewsArticle.setUpdateTime(DateUtil.getDateTime());

            HktNewsCategory newsCategory = new HktNewsCategory();
            newsCategory.setId(hktNewsArticle.getCid());
            HktNewsCategory category = categoryService.queryCategory(newsCategory);
            if (category == null) {
                ret.setFail().setMsg("新闻分类设置错误");
            }

            if (StringUtils.isNull(hktNewsArticle.getPublishTime()))
                hktNewsArticle.setPublishTime(DateUtil.getDateTime());

            String tag = "";
            for (HktUrlLinkVo vo : hktNewsArticle.getKeywords()) {
                tag += vo.getTag() + "," + vo.getTagLink() + "|";
            }
            hktNewsArticle.setTagId(tag);

            if (!StringUtils.isNull(hktNewsArticle.getContent())) {
                OSSClient ossClient = new OSSClient(aliyunOSSProperties.getEndpoint(), aliyunOSSProperties.getAccessKeyId(), aliyunOSSProperties.getAccessKeySecret());
                String url = aliyunOssService.uploadForStr(ossClient, hktNewsArticle.getContent(), "newInfo/" + System.currentTimeMillis() + ".html");
                hktNewsArticle.setContent(url);
            }

            category.setNewsNum(category.getNewsNum() + 1);

            List<String> sqls = new ArrayList<>();
            sqls.add(ExecSqlLib.GetInsertSql(hktNewsArticle));
            sqls.add(ExecSqlLib.GetUpdateSql(category));

            if (this.baseJdbcDao.executeTransaction(sqls)) {//存入数据库
                HktNewsArticle newsArticle = new HktNewsArticle();
                newsArticle.setLanguageId(hktNewsArticle.getLanguageId());
                newsArticle.setTitle(hktNewsArticle.getTitle());
                newsArticle.setCid(hktNewsArticle.getCid());
                HktNewsArticle query = this.baseJdbcDao.query(ExecSqlLib.GetQuerySql(newsArticle), hktNewsArticle);
                if (!StringUtils.isNull(query.getId())) {
                    mongoHelper.save(query);
                }
                categoryMongoHelper.mongoUpdate(category.getId(), category, HktNewsCategory.class);
                ret.setOk().set("msg", "新增文章成功");
            } else {
                ret.setFail().set("msg", "新增文章失败");
            }
        } else {
            //更新
            HktNewsArticle find = new HktNewsArticle();
            find.setId(hktNewsArticle.getId());
            find = (HktNewsArticle) mongoHelper.findOne(find, HktNewsArticle.class);
            if (find == null) return ret.setFail().set("msg", "不存在需要修改的对象");

            if (hktNewsArticle.getKeywords() != null) {
                String url = "";
                for (HktUrlLinkVo vo : hktNewsArticle.getKeywords()) {
                    url += vo.getTag() + "," + vo.getTagLink() + "|";
                }
                find.setTagId(url);
            }
            if (!StringUtils.isNull(hktNewsArticle.getContent())) {
                if (find.getContent().endsWith(".html")) {
                    OSSClient ossClient = new OSSClient(aliyunOSSProperties.getEndpoint(), aliyunOSSProperties.getAccessKeyId(), aliyunOSSProperties.getAccessKeySecret());
                    aliyunOssService.uploadForStr(ossClient, hktNewsArticle.getContent(), find.getContent().substring(find.getContent().indexOf(aliyunOSSProperties.getFileHost()) + aliyunOSSProperties.getFileHost().length() + 1));
                } else {
                    OSSClient ossClient = new OSSClient(aliyunOSSProperties.getEndpoint(), aliyunOSSProperties.getAccessKeyId(), aliyunOSSProperties.getAccessKeySecret());
                    String url = aliyunOssService.uploadForStr(ossClient, hktNewsArticle.getContent(), "newInfo/" + System.currentTimeMillis() + ".html");
                    find.setContent(url);
                }
            }

            if (!StringUtils.isNull(hktNewsArticle.getTitle())) find.setTitle(hktNewsArticle.getTitle());

            if (!StringUtils.isNull(hktNewsArticle.getImg())) find.setImg(hktNewsArticle.getImg());
            if (!StringUtils.isNull(hktNewsArticle.getIsTop())) find.setIsTop(hktNewsArticle.getIsTop());
            if (!StringUtils.isNull(hktNewsArticle.getDescription())) find.setDescription(hktNewsArticle.getDescription());
            find.setUpdateTime(DateUtil.getDateTime());

            List<String> sqls = new ArrayList<>();
            HktNewsCategory category = null;
            HktNewsCategory oldCategory = null;
            if (!StringUtils.isNull(hktNewsArticle.getCid()) && !hktNewsArticle.getCid().equals(find.getCid())) {
                HktNewsCategory newsCategory = new HktNewsCategory();
                newsCategory.setId(hktNewsArticle.getCid());
                category = categoryService.queryCategory(newsCategory);
                if (category == null) {
                    ret.setFail().setMsg("新闻分类设置错误");
                }
                category.setNewsNum(category.getNewsNum() + 1);
                sqls.add(ExecSqlLib.GetUpdateSql(category));

                newsCategory.setId(find.getCid());
                oldCategory = categoryService.queryCategory(newsCategory);
                if (oldCategory != null) {
                    oldCategory.setNewsNum(oldCategory.getNewsNum() - 1);
                    if (oldCategory.getNewsNum() < 0) {
                        oldCategory.setNewsNum(0);
                    }
                    sqls.add(ExecSqlLib.GetUpdateSql(oldCategory));
                }

                find.setCid(hktNewsArticle.getCid());
            }

            sqls.add(ExecSqlLib.GetUpdateSql(find));
            if (this.baseJdbcDao.executeTransaction(sqls)) {
                //MongoDB更新
                mongoHelper.mongoUpdate(hktNewsArticle.getId(), find, HktNewsArticle.class);
                if (category != null) {
                    categoryMongoHelper.mongoUpdate(category.getId(), category, HktNewsCategory.class);
                }
                if (oldCategory != null) {
                    categoryMongoHelper.mongoUpdate(oldCategory.getId(), oldCategory, HktNewsCategory.class);
                }
                ret.setOk().set("msg", "修改文章成功");
            } else {
                ret.setFail().set("msg", "修改文章失败");
            }
        }
        return ret;
    }

    @Override
    public Ret deleteArticle(HktAdmin admin, HktNewsArticle hktNewsArticle) {

        //更新
        HktNewsArticle find = new HktNewsArticle();
        find.setId(hktNewsArticle.getId());
        find = (HktNewsArticle) mongoHelper.findOne(find, HktNewsArticle.class);
        if (find == null) return Ret.create().setFail().set("msg", "不存在需要修改的对象");

        HktNewsCategory newsCategory = new HktNewsCategory();
        newsCategory.setId(find.getCid());
        HktNewsCategory category = categoryService.queryCategory(newsCategory);

        List<String> sqls = new ArrayList<>();
        if (category == null) {
            // return Ret.create().setFail().setMsg("新闻分类设置错误");
        } else {
            category.setNewsNum(category.getNewsNum() - 1);
            if (category.getNewsNum() < 0) category.setNewsNum(0);
            sqls.add(ExecSqlLib.GetUpdateSql(category));
        }
        sqls.add(ExecSqlLib.GetDeleteByIdSql(find.getId(), find));

        //新闻自身删除
        if (this.baseJdbcDao.executeTransaction(sqls)) {
            //MongoDB删除对应信息
            mongoHelper.removeById(hktNewsArticle.getId(), HktNewsArticle.class);
            if (!StringUtils.isNull(find.getContent())) {
                OSSClient ossClient = new OSSClient(aliyunOSSProperties.getEndpoint(), aliyunOSSProperties.getAccessKeyId(), aliyunOSSProperties.getAccessKeySecret());
                aliyunOssService.deleteFile(ossClient, find.getContent().substring(find.getContent().indexOf(aliyunOSSProperties.getFileHost())));
            }
            if (category != null) {
                categoryMongoHelper.mongoUpdate(category.getId(), category, HktNewsCategory.class);
            }
            return Ret.create().setOk();
        } else {
            return Ret.create().setFail().setMsg("删除失败");
        }
    }

    @Override
    public HktNewsArticle queryPrevArticle(HktNewsArticle hktNewsArticle) {
        String sql = "select id,title FROM hkt_news_article where id < "+hktNewsArticle.getId()+" ORDER BY id DESC LIMIT 1";
        return this.baseJdbcDao.query(sql,hktNewsArticle);
    }

    @Override
    public HktNewsArticle queryNextArticle(HktNewsArticle hktNewsArticle) {
        String sql = "select id,title FROM hkt_news_article where id > "+hktNewsArticle.getId()+" LIMIT 1";
        return this.baseJdbcDao.query(sql,hktNewsArticle);
    }

    @Override
    public Page<HktNewsArticle> queryPage(HktNewsArticle hktNewsArticle) {

        String title = hktNewsArticle.getTitle();
        hktNewsArticle.setTitle(null);
        Query query = mongoHelper.createQuery(hktNewsArticle, HktNewsArticle.class);
        if (!StringUtils.isNull(title)) {
            query.addCriteria(Criteria.where("title").regex(title));
        }
        query.with(new Sort(Sort.Direction.DESC, "isTop",  "publishTime","isHot",  "hit")).limit(12);

        Page<HktNewsArticle> page = mongoHelper.findPage(hktNewsArticle, query, HktNewsArticle.class);
        List<HktNewsCategory> categories = categoryService.queryNewsCategoryList(new HktNewsCategory());

        Map<String, HktNewsCategory> categoryMap = new HashMap<>();
        for (HktNewsCategory cat : categories) categoryMap.put(cat.getId(), cat);

        for (HktNewsArticle news : page.getRecords()) {
            HktNewsCategory category = categoryMap.get(news.getCid());
            if (category != null) news.setCatName(category.getName());
            SetKeyword(news);
        }
        return page;
    }

    private void SetKeyword(HktNewsArticle news) {
        news.setKeywords(new ArrayList<>());
        if (!StringUtils.isNull(news.getTagId())) {
            String[] arr = news.getTagId().split("\\|");
            for (String a : arr) {
                String[] arr1 = a.split(",");
                if (arr1.length < 2) continue;
                HktUrlLinkVo vo = new HktUrlLinkVo();
                vo.setTag(arr1[0]);
                vo.setTagLink(arr1[1]);
                news.getKeywords().add(vo);
            }
        }
    }


    @Override
    public HktNewsArticle queryArticle(HktNewsArticle hktNewsArticle) {
        HktNewsArticle res = (HktNewsArticle) mongoHelper.findOne(hktNewsArticle, HktNewsArticle.class);
        if (res == null) return null;
        SetKeyword(res);

        HktNewsCategory category = new HktNewsCategory();
        category.setId(res.getCid());
        HktNewsCategory categories = categoryService.queryCategory(category);
        if (categories != null) {
            res.setCatName(category.getName());
        }

        if (!StringUtils.isNull(res.getContent())) {
            OSSClient ossClient = new OSSClient(aliyunOSSProperties.getEndpoint(), aliyunOSSProperties.getAccessKeyId(), aliyunOSSProperties.getAccessKeySecret());
            res.setContent(aliyunOssService.getTxtMsg(ossClient, res.getContent()));
        }
        return res;
    }

    @Override
    public Map<String, List<Map<String, Object>>> queryList(String language) {
        HktNewsCategory newsCategory = new HktNewsCategory();
        newsCategory.setLanguageId(Integer.parseInt(language));
        List<HktNewsCategory> categories = mongoHelper.find(newsCategory, HktNewsCategory.class);

        Map<String, List<Map<String, Object>>> res = new HashMap<>();
        for (HktNewsCategory category : categories) {

            HktNewsArticle article = new HktNewsArticle();
            article.setCid(category.getId());

            List<Map<String, Object>> tempList = new ArrayList<>();
            Query query = mongoHelper.createQuery(article, HktNewsArticle.class);
            query.with(new Sort(Sort.Direction.DESC, "isTop", "isHot", "hit")).limit(10);
            List<HktNewsArticle> hktNewsArticles = mongoHelper.find(query, HktNewsArticle.class);
            for (HktNewsArticle news : hktNewsArticles) {
                SetKeyword(news);

                Map<String, Object> tempMap = new HashMap<>();
                tempMap.put("id", news.getId());
//                tempMap.put("languageId", news.getLanguageId());
                tempMap.put("title", news.getTitle());
                tempMap.put("cid", news.getCid());
                tempMap.put("catName", news.getCatName());
                tempMap.put("img", news.getImg());
//                tempMap.put("content", null);
                tempMap.put("description", news.getDescription());
                tempMap.put("hit", news.getHit());
                tempMap.put("isHot", news.getIsHot());
                tempMap.put("isTop", news.getIsTop());
                tempMap.put("keywords", news.getKeywords());
                tempList.add(tempMap);
            }
            res.put(category.getId(), tempList);
        }

        //阅读排行榜
        res.put("hit", queryHotArticle(language, "hit", 20));
        return res;
    }

    @Override
    public List<Map<String, Object>> queryHotArticle(String language, String queryOption, int getCount) {
        Criteria criteria = new Criteria();
        criteria.andOperator(Criteria.where("languageId").is(Integer.parseInt(language)));

        Query query = new Query(criteria);
        query.with(new Sort(Sort.Direction.DESC, queryOption));
        query.limit(getCount);
        List<HktNewsArticle> hitList = mongoHelper.find(query, HktNewsArticle.class);

        List<Map<String, Object>> tempList = new ArrayList<>();
        for (HktNewsArticle news : hitList) {
            SetKeyword(news);

            Map<String, Object> tempMap = new HashMap<>();
            tempMap.put("id", news.getId());
            tempMap.put("title", news.getTitle());
//            tempMap.put("catName", news.getCatName());
//            tempMap.put("img", news.getImg());
//            tempMap.put("description", news.getDescription());
            tempMap.put("hit", news.getHit());
//            tempMap.put("keywords", news.getKeywords());
            tempList.add(tempMap);
        }
        return tempList;
    }
}
