package com.yihu.wlyy.service.common;

import com.yihu.wlyy.entity.organization.Hospital;
import com.yihu.wlyy.entity.address.Town;
import com.yihu.wlyy.entity.doctor.profile.Doctor;
import com.yihu.wlyy.repository.address.TownDao;
import com.yihu.wlyy.repository.doctor.DoctorDao;
import com.yihu.wlyy.repository.organization.HospitalDao;
import com.yihu.wlyy.service.BaseService;
import com.yihu.wlyy.util.HttpUtil;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Created by lyr on 2016/08/10.
 */
@Service
@Transactional
public class QrcodeService extends BaseService {
    @Autowired
    private DoctorDao doctorDao;
    @Autowired
    private HospitalDao hospitalDao;
    @Autowired
    private TownDao townDao;

    /**
     * 所有医生二维码生成
     *
     * @param token
     * @return
     * @throws Exception
     */
    public boolean makeDoctorQrCode(String hospital, String token) throws Exception {
        // 查找所有医生
        Iterable<Doctor> doctors = null;

        if (StringUtils.isNotEmpty(hospital)) {
            doctors = doctorDao.findHospitalDoctors(hospital);
        } else {
            doctors = doctorDao.findAllDoctors();
        }

        String path = QrcodeService.class.getResource("/").getPath().replace("/WEB-INF/classes/", "")
                + File.separator + "qrcode";

        for (Doctor doctor : doctors) {
            // 二维码内容
            String content = "qr_" + doctor.getCode() + "_" + doctor.getName();
            // 二维码图片文件名
            String fileName = doctor.getMobile();
            if (StringUtils.isEmpty(fileName)) {
                continue;
            }
            // 通过微信接口生成医生二维码
            makeQrcodeFromWeiXin(content, fileName.replaceAll("\r\n", ""), path, token);
            doctor.setQrcode(fileName + ".png");
        }

        return true;
    }

    /**
     * 生成社区医院二维码
     *
     * @param hospital
     * @param token
     * @return
     * @throws Exception
     */
    public boolean makeHospitalQrcode(String hospital,String token)throws Exception{
        // 查找所有医生
        List<Hospital> hospitals = new ArrayList<>();

        if (StringUtils.isNotEmpty(hospital)) {
            Hospital hos = hospitalDao.findByCode(hospital);
            hospitals.add(hos);
        } else {
            hospitals = hospitalDao.findAllSqHospital();
        }

        String path = QrcodeService.class.getResource("/").getPath().replace("/WEB-INF/classes/", "")
                + File.separator + "qrcode";

        for (Hospital hos : hospitals) {
            // 二维码内容
            String content = "hs_" + hos.getCode() + "_" + hos.getName();
            // 二维码图片文件名
            String fileName = hos.getCode();
            if (StringUtils.isEmpty(fileName)) {
                continue;
            }
            // 通过微信接口生成医生二维码
            makeQrcodeFromWeiXin(content, fileName.replaceAll("\r\n", ""), path, token);
        }

        return true;
    }

    /**
     * 生成区二维码
     *
     * @param town
     * @param token
     * @return
     * @throws Exception
     */
    public boolean makeTownQrcode(String town,String token) throws Exception{
        try{
            Town twn = townDao.findByCode(town);

            if (twn != null) {
                // 二维码内容
                String content = "tw_" + twn.getCode() + "_" + twn.getName();
                // 二维码图片文件名
                String fileName = twn.getCode();
                String path = QrcodeService.class.getResource("/").getPath().replace("/WEB-INF/classes/", "")
                        + File.separator + "qrcode";

                // 通过微信接口生成区二维码
                makeQrcodeFromWeiXin(content, fileName.replaceAll("\r\n", ""), path, token);

                return true;
            } else {
                throw new Exception("can not find town info");
            }
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 社区二维码生成打包为zip
     *
     * @param token
     * @return
     * @throws Exception
     */
    public File downloadHospitalQrCodes(String area, String token) throws Exception {
        // 查找所有医生
        List<Hospital> Hospitals = null;
        String zipFileName = "hospital_qrcode";

        if(StringUtils.isEmpty(area)){
            Hospitals  = hospitalDao.findAllSqHospital();
        }else{
            Hospitals =  hospitalDao.findAreaSqHospital(area);
        }

        String path = QrcodeService.class.getResource("/").getPath().replace("/WEB-INF/classes/", "")
                + File.separator + "qrcode_download";
        File file = new File(path);

        // 删除文件夹、文件
        if (file.exists()) {
            File[] files = file.listFiles();
            if (files != null && files.length > 0) {
                for (File f : files) {
                    f.delete();
                }
            }
            file.delete();
        }

        if (Hospitals != null) {
            for (Hospital hos : Hospitals) {
                // 二维码内容
                String content = "hs_" + hos.getCode() + "_" + hos.getName();
                String hosLevel = "";

                if (hos.getLevel() == 1) {
                    hosLevel = "医院";
                } else if (hos.getLevel() == 2) {
                    hosLevel = "社区";
                }

                // 二维码图片文件名
                String fileName = hos.getName() + "_" + hos.getCode()+ "_" + hosLevel;
                if (StringUtils.isEmpty(fileName)) {
                    continue;
                }
                // 通过微信接口生成医生二维码
                makeQrcodeFromWeiXin(content, fileName.replaceAll("\r\n", ""), path, token);
            }

            File zipFile = new File(path.replace("qrcode_download", "") + zipFileName + ".zip");
            if (zipFile.exists()) {
                zipFile.delete();
            }

            // 打包文件夹
            if (fileToZip(path, path.replace("qrcode_download", ""), zipFileName)) {
                return new File(path.replace("qrcode_download", "") + zipFileName + ".zip");
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    /**
     * 医生二维码生成打包为zip
     *
     * @param token
     * @return
     * @throws Exception
     */
    public File downloadDoctorQrCodes(String hospital, String token) throws Exception {
        // 查找所有医生
        Iterable<Doctor> doctors = null;
        String zipFileName = "doctor_qrcode";

        if (StringUtils.isNotEmpty(hospital)) {
            doctors = doctorDao.findHospitalDoctors(hospital);
        } else {
            doctors = doctorDao.findAllDoctors();
        }

        String path = QrcodeService.class.getResource("/").getPath().replace("/WEB-INF/classes/", "")
                + File.separator + "qrcode_download";
        File file = new File(path);

        // 删除文件夹、文件
        if (file.exists()) {
            File[] files = file.listFiles();
            if (files != null && files.length > 0) {
                for (File f : files) {
                    f.delete();
                }
            }
            file.delete();
        }

        if (doctors != null) {
            for (Doctor doctor : doctors) {
                if (StringUtils.isNotEmpty(hospital)) {
                    zipFileName = doctor.getHosptialName();
                }

                // 二维码内容
                String content = "qr_" + doctor.getCode() + "_" + doctor.getName();
                String doctorLevel = "";

                if (doctor.getLevel() == 1) {
                    doctorLevel = "专科医生";
                } else if (doctor.getLevel() == 2) {
                    doctorLevel = "全科医生";
                } else if (doctor.getLevel() == 3) {
                    doctorLevel = "健康管理师";
                }

                // 二维码图片文件名
                String fileName = doctor.getName() + "_" + doctor.getMobile() + "_" + doctorLevel;
                if (StringUtils.isEmpty(fileName)) {
                    continue;
                }
                // 通过微信接口生成医生二维码
                makeQrcodeFromWeiXin(content, fileName.replaceAll("\r\n", ""), path, token);
            }

            File zipFile = new File(path.replace("qrcode_download", "") + zipFileName + ".zip");
            if (zipFile.exists()) {
                zipFile.delete();
            }

            // 打包文件夹
            if (fileToZip(path, path.replace("qrcode_download", ""), zipFileName)) {
                return new File(path.replace("qrcode_download", "") + zipFileName + ".zip");
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    /**
     * 区二维码生成打包为zip
     *
     * @param city
     * @param token
     * @return
     * @throws Exception
     */
    public File downLoadTownQrcodes(String city,String token) throws Exception{
        // 查找所有医生
        Iterable<Town> towns = null;
        String zipFileName = "town_qrcode";

        if (StringUtils.isNotEmpty(city)) {
            towns = townDao.findByCity(city);
        } else {
            towns = townDao.findAll();
        }

        String path = QrcodeService.class.getResource("/").getPath().replace("/WEB-INF/classes/", "")
                + File.separator + "qrcode_download";
        File file = new File(path);

        // 删除文件夹、文件
        if (file.exists()) {
            File[] files = file.listFiles();
            if (files != null && files.length > 0) {
                for (File f : files) {
                    f.delete();
                }
            }
            file.delete();
        }

        if (towns != null) {
            for (Town town : towns) {
                if (StringUtils.isNotEmpty(city)) {
                    zipFileName = town.getCity();
                }

                // 二维码内容
                String content = "tw_" + town.getCode() + "_" + town.getName();

                // 二维码图片文件名
                String fileName = town.getName() + "_" + town.getCode();
                if (StringUtils.isEmpty(fileName)) {
                    continue;
                }
                // 通过微信接口生成医生二维码
                makeQrcodeFromWeiXin(content, fileName.replaceAll("\r\n", ""), path, token);
            }

            File zipFile = new File(path.replace("qrcode_download", "") + zipFileName + ".zip");
            if (zipFile.exists()) {
                zipFile.delete();
            }

            // 打包文件夹
            if (fileToZip(path, path.replace("qrcode_download", ""), zipFileName)) {
                return new File(path.replace("qrcode_download", "") + zipFileName + ".zip");
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    /**
     * 打包文件夹
     *
     * @param sourcePath
     * @param zipPath
     * @param zipName
     * @return
     * @throws Exception
     */
    public boolean fileToZip(String sourcePath, String zipPath, String zipName) throws Exception {
        File sourceFile = new File(sourcePath);
        File zipFile = new File(zipPath + File.separator + zipName + ".zip");
        File[] files = sourceFile.listFiles();
        FileOutputStream fos = new FileOutputStream(zipFile);
        ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(fos));

        if (files != null) {
            byte[] bufs = new byte[1024 * 10];
            for (int i = 0; i < files.length; i++) {
                // 创建ZIP实体,并添加进压缩包
                ZipEntry zipEntry = new ZipEntry(files[i].getName());
                zos.putNextEntry(zipEntry);
                // 读取待压缩的文件并写进压缩包里
                FileInputStream fis = new FileInputStream(files[i]);
                BufferedInputStream bis = new BufferedInputStream(fis, 1024 * 10);
                int read = 0;
                while ((read = bis.read(bufs, 0, 1024 * 10)) != -1) {
                    zos.write(bufs, 0, read);
                }
                bis.close();
                fis.close();
            }
        }

        zos.close();
        fos.close();

        return true;
    }

    /**
     * 生成某个医生的二维码
     *
     * @param doctor
     * @param token
     * @return
     * @throws Exception
     */
    public boolean makeDoctorQrcode(String doctor, String token) throws Exception {
        Doctor doc = doctorDao.findByCode(doctor);

        if (doc != null) {
            // 二维码内容
            String content = "qr_" + doc.getCode() + "_" + doc.getName();
            // 二维码图片文件名
            String fileName = doc.getMobile();
            String path = QrcodeService.class.getResource("/").getPath().replace("/WEB-INF/classes/", "")
                    + File.separator + "qrcode";

            // 通过微信接口生成医生二维码
            makeQrcodeFromWeiXin(content, fileName.replaceAll("\r\n", ""), path, token);
            doc.setQrcode(fileName + ".png");

            return true;
        } else {
            throw new Exception("找不到对应医生信息!");
        }
    }

    /**
     * 从微信生成二维码并下载到本地
     *
     * @param content
     * @param fileName
     * @param path
     * @param token
     * @throws IOException
     */
    public String makeQrcodeFromWeiXin(String content, String fileName, String path, String token) throws Exception {
        try {
            String token_url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + token;
            String params = "{\"action_name\": \"QR_LIMIT_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \"" + content + "\"}}}";
            String result = HttpUtil.sendPost(token_url, params);

            if (!StringUtils.isEmpty(result)) {
                JSONObject json = new JSONObject(result);

                if (json.has("ticket")) {
                    String file = path + File.separator + fileName + ".png";
                    // 保存路径
                    File pathFile = new File(path);
                    // 保存文件
                    File outputFile = new File(file);
                    // 路径不存在则创建
                    if (!pathFile.exists()) {
                        pathFile.mkdir();
                    }
                    // 文件已存在则删除
                    if (outputFile.exists()) {
                        outputFile.delete();
                    }
                    // 请求输入流
                    InputStream inputStream = null;
                    // 二维码图片输出流
                    FileOutputStream outputStream = new FileOutputStream(file);
                    // 下载二维码图片
                    URL urlGet = new URL("https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket="
                            + json.get("ticket").toString());
                    HttpURLConnection connection = (HttpURLConnection) urlGet.openConnection();
                    connection.connect();
                    inputStream = connection.getInputStream();
                    // 保存图片
                    byte[] data = new byte[1024];
                    int len = 0;

                    while ((len = inputStream.read(data)) != -1) {
                        outputStream.write(data, 0, len);
                    }

                    if (inputStream != null) {
                        inputStream.close();
                    }
                    if (outputStream != null) {
                        outputStream.close();
                    }

                    return file;
                } else {
                    throw new Exception("请求微信生成二维码失败!");
                }
            } else {
                throw new Exception("请求微信生成二维码失败!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception(e.getMessage());
        }
    }


}
