package com.controller;

import com.alibaba.fastjson.JSON;
import com.config.BaseController;
import com.config.ControllerInterface;
import com.itextpdf.text.*;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import com.jfinal.aop.Before;
import com.jfinal.aop.Clear;
import com.jfinal.ext.interceptor.POST;
import com.jfinal.kit.PathKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.model.Book;
import com.model.BookDetail;
import com.model.BookDiaobo;
import com.model.BookZhuxiao;
import com.service.BookDetailService;
import com.service.SysConfigService;
import com.tools.ISBNTools;
import com.tools.JwtUtils;
import com.utils.CommonUtils;
import org.apache.commons.lang3.StringUtils;
import org.krysalis.barcode4j.HumanReadablePlacement;
import org.krysalis.barcode4j.impl.code128.Code128Bean;
import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.util.*;
import java.util.List;

/**
 * 图书详细信息操作
 * 2018-10-23
 * wush
 */
@ControllerInterface(path="/bookDetail")
public class BookDetailController extends BaseController {
    BookDetailService service = BookDetailService.me;


    SysConfigService sysConfigService =SysConfigService.me;

    public void list(){
        try{
            Book bean = getBean(Book.class,"bean");
            //根据时间排序 timesortd正序 timesorta倒序
            String timesortd = this.getPara("bean.timesortd");
            String timesorta = this.getPara("bean.timesorta");
            String bookstatus = getPara("bookstatus");
            String status = getPara("status");
            String startDate = getPara("startDate");
            String endDate = getPara("endDate");

            String barcode = getPara("barcode");
            Integer library = getParaToInt("library");
            String field = this.getPara("field");




            Page<BookDetail> page = service.paginate(this.getParaToInt("pageNumber"),this.getParaToInt("pageSize"),timesortd,timesorta,bean,  bookstatus,status,library,barcode,startDate,endDate,field);
            success(page);
        }catch(Exception e){
            e.printStackTrace();
            fail();
        }
    }

    public void booktotal(){
        try{
            Book bean = getBean(Book.class,"bean");
            //根据时间排序 timesortd正序 timesorta倒序
            String timesortd = this.getPara("bean.timesortd");
            String timesorta = this.getPara("bean.timesorta");
            String bookstatus = getPara("bookstatus");
            String status = getPara("status");

            String barcode = getPara("barcode");
            Integer library = getParaToInt("library");
            success(service.booktotal(bean,  bookstatus,status,library,barcode));
        }catch(Exception e){
            e.printStackTrace();
            fail();
        }
    }

    /**
     * 根据书本id获取馆藏信息
     */
    public void findByBookId(){
        int bookId =this.getParaToInt("bookId", 0);
        if(bookId == 0){
            fail();
        }
        success(service.findByBookId(bookId));
    }

    /**
     * 批量保存信息
     */
    public void batchSaveInfo(){
        String jstr = this.getPara("jsonStr");
        String token = this.getPara("token");
        int operatorid = JwtUtils.validateJWTForUserId(token);
        if(operatorid == 0){
            fail(3,"token错误");
            return;
        }
        List<BookDetail> list = JSON.parseArray(jstr,BookDetail.class);
        service.batchSaveInfo(list,operatorid);
        success();
    }

    /**
     * 根据isbn查询detail列表
     */
    public void findDetailListById(){
        int orgid = this.getParaToInt("orgid",0);
        if(orgid == 0) {
            fail(1,"请求参数不完整!");
            return;
        }
        String id = getPara("id");
        success(service.findDetailListById(id,orgid));
    }

    public void findDetailList(){
        int orgid = this.getParaToInt("orgid",0);
        if(orgid == 0) {
            fail(1,"请求参数不完整!");
            return;
        }
        String id = getPara("id");
        success(service.findDetailList(id,orgid));
    }


    public void deleteById(){
        int orgid = this.getParaToInt("orgid",0);
        if(orgid == 0) {
            fail(1,"请求参数不完整!");
            return;
        }
        int id = getParaToInt("id");
        service.deleteById(id,orgid);
        success();
    }

     public void deleteByDetailId(){
         int orgid = this.getParaToInt("orgid",0);
         if(orgid == 0) {
             fail(1,"请求参数不完整!");
             return;
         }
         int id = getParaToInt("id",0);
         if(id == 0) {
             fail(1,"请求参数不完整!");
             return;
         }
         Record record = Db.findFirst("select d.id,d.bookid from t_book_detail d left join t_book b on d.bookid = b.id where d.id = ? and b.orgid=?",id,orgid);
         if(CommonUtils.isNotNullOrNotEmpty(record)){
             Db.delete("delete from t_book_detail where id = ?",record.getInt("id"));
             success();
         } else {
             fail(0,"查询不到书籍信息");
         }
     }

   public void updatePiciOrLibrary(){
        String token = this.getPara("token");
        int operatorid = JwtUtils.validateJWTForUserId(token);
        if(operatorid == 0){
            fail(3,"token错误");
            return;
        }
        Integer orgid=getParaToInt("orgid");
        String detailid = this.getPara("detailid");
        String libraryorpiciid = this.getPara("libraryorpiciid");
        int type = this.getParaToInt("type");
        if(1 == type) {
            Db.update("update t_book_detail set libraryid=? where id = (select * from (select d.id from t_book_detail d inner join t_book b on d.bookid = b.id where d.id = ? and b.orgid = ? ) t)",libraryorpiciid,detailid,orgid);
        }else if(type == 3){
            //更改条码
            Record r = Db.findFirst("SELECT COUNT(*) as num  FROM t_book_detail a INNER JOIN t_book b ON a.bookid = b.id WHERE a.id != ? AND a.barcode = ? AND b.orgid = ? ",detailid,libraryorpiciid,orgid);
            Integer num = r.getInt("num");
            if(num>0){
                success(1,"该条码已存在!");
                return;
            }else {
                Db.update("update t_book_detail set barcode=? where id = (select * from (select d.id from t_book_detail d inner join t_book b on d.bookid = b.id where d.id = ? and b.orgid = ? ) t)",libraryorpiciid,detailid,orgid);
            }
        } else {
            Db.update("update t_book_detail set piciid=? where id = (select * from (select d.id from t_book_detail d inner join t_book b on d.bookid = b.id where d.id = ? and b.orgid = ? ) t)",libraryorpiciid,detailid,orgid);
        }
        success();
    }

    public void bookStatus(){

        String token = this.getPara("token");
        int operatorid = JwtUtils.validateJWTForUserId(token);
        if(operatorid == 0){
            fail(3,"token错误");
            return;
        }
        Integer orgid=getParaToInt("orgid");


        List<String> idList =new ArrayList<String>(Arrays.asList(getParaValues("bookDetailIDList[]")));
        List<String> bookIDList =new ArrayList<String>(Arrays.asList(getParaValues("bookIDList[]")));


        Integer status =getParaToInt("status");
        String reason = getPara("reason");
        StringBuffer idsbuf=new StringBuffer();
        for (String id :idList){
            idsbuf.append(id).append(",");
        }
        idsbuf.append("-1");
        List<Record> list =service.findNotCancelBook(idsbuf.toString());

        List<String> bookTitleList = new ArrayList<String>();

        for (Record r : list){
            if (idList.contains(r.getStr("id"))){
                idList.remove(r.getStr("id"));
                bookTitleList.add(r.getStr("title"));
            }
        }

        idsbuf.setLength(0);
        for (String id :idList){
            idsbuf.append(id).append(",");
        }
        idsbuf.append("-1");

        service.updateBookDetailStatus(idsbuf.toString(),status,orgid,reason,operatorid);
        service.updateBookNum(bookIDList);

        success(bookTitleList);
    }





    public void findBookByBarCode(){
        String barcode = getPara("barcode");
        Integer orgid=getParaToInt("orgid");
        barcode= CommonUtils.formatBarcode(barcode,sysConfigService.findOrgSetting(orgid));
        Record record=service.findBookByBarcode(orgid,barcode);
        if (record==null){
            fail(0,"没有找到记录");
        }else{
            success(record);
        }
    }

    public void updateRFIFByBarCode(){
        try {
            Map info = JwtUtils.validateJWTForMap(this.getPara("token"));
            if(info == null){
                fail_token();
                return;
            }
            int orgid = (int)info.get("orgid");
            String rfid=getPara("rfid");
            String barcode = getPara("barcode");
            service.updateRFIFByBarCode(barcode,rfid,orgid);
            success();
        }catch (Exception e){
            fail(0,e.getMessage());
        }

    }



    public void updateBarCode(){
        String newbarcode=getPara("newbarcode");
        Integer orgid=getParaToInt("orgid");
        newbarcode= CommonUtils.formatBarcode(newbarcode,sysConfigService.findOrgSetting(orgid));
        if (null !=service.bookBarcodeExists(orgid,newbarcode)){
            fail(0,"新条码已经被使用，请更换条码！");
            return;
        }else {
            Integer bookdetailid=getParaToInt("bookdetailid");
            service.updateBarCode(newbarcode,bookdetailid);
            success(newbarcode);
        }
    }

    public void batchFindBookInfoByBarcodes(){
        String barcodes = getPara("barcodes");
        String tag = getPara("tag");
        String token = this.getPara("token");
        int operatorid = JwtUtils.validateJWTForUserId(token);
        if(operatorid == 0){
            fail(3,"token错误");
            return;
        }
        int orgid = this.getParaToInt("orgid",0);
        if(orgid == 0) {
            fail(1,"请求参数不完整!");
            return;
        }

        String sql ="select d.rfid,d.id,d.barcode,b.title,l.library,IFNULL((SELECT j.status FROM t_jieyue j WHERE j.bookdetailid=d.id ORDER BY j.id DESC LIMIT 1),1) AS status from t_book b " +
                "left join t_book_detail d on b.id = d.bookid " +
                "left join t_library l on d.libraryid=l.id where d.bookstatus=1 and  b.orgid = ? and (d.barcode in ("+barcodes+") or d.rfid in ("+tag+"))";

        logger.debug(sql);
        List<Record> bookinfoList = Db.find(sql,orgid);
        success(bookinfoList);
    }



    /**
     * 生成条形码
     * @param barCode 生成条码码的编号
     * @throws Exception
     */
    private static byte[] genBarCodeJpg(String barCode) throws Exception{
        Code128Bean bean = new Code128Bean();
        final int dpi = 250;
        //样式
        bean.setModuleWidth(0.21);
        bean.setBarHeight(7);
        bean.doQuietZone(false);
        bean.setQuietZone(2);

        //两边空白区
        bean.setFontName("Helvetica");
        bean.setFontSize(3);
        bean.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM);

        ByteArrayOutputStream out = null;
        try {
            out = new ByteArrayOutputStream();
            BitmapCanvasProvider canvas = new BitmapCanvasProvider(out,
                    "image/png", dpi, BufferedImage.TYPE_BYTE_BINARY
                    , true, 0);

            bean.generateBarcode(canvas, barCode);
            canvas.finish();
            return out.toByteArray();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null)
                    out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 将条形码写入PDF文件
     * @param pdfFile PDF类型的文件(word等需要转换为PDF)
     * @param barCode 生成条形码的code
     * @return
     * @throws Exception
     */
    private File pdfAddControlCode(File pdfFile, String barCode)throws Exception {
        if(CommonUtils.isNullOrEmpty(barCode)){
            return pdfFile;
        }

        BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        Font titlefont = new Font(bfChinese, 19, Font.NORMAL);
//        com.itextpdf.text.Font wf = new com.itextpdf.text.Font(false, 19);
        titlefont.setColor(BaseColor.BLUE);

        InputStream is = new FileInputStream(pdfFile);
        PdfReader reader = new PdfReader(is);

        File file = File.createTempFile(String.valueOf(System.nanoTime()), ".pdf");
        PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(file));

        //设置文件为只读
        //stamp.setEncryption(null, OWNER_PASSWORD.getBytes(), 0, PdfWriter.ENCRYPTION_AES_128);

        //PDF文件的总页数
        //int number_of_pages = reader.getNumberOfPages();
        //取得第一页
        com.itextpdf.text.Rectangle rectangle = reader.getPageSize(0);
        float width = rectangle.getWidth();
        float height = rectangle.getHeight();

        //是否竖版
        //boolean direction = height >= width;

        //取得PDF文件的第一页
        // getOverContent 水印会把正文盖住    getUnderContent 水印会被正文的图片盖住
        PdfContentByte contentByte = stamp.getOverContent(0);

        PdfGState gs = new PdfGState();
        gs.setFillOpacity(0.7f);// 设置透明度
        gs.setStrokeOpacity(0.7f);
        contentByte.setGState(gs);

        //在第一页加上条形码
        com.itextpdf.text.Image img = com.itextpdf.text.Image.getInstance(genBarCodeJpg(barCode));
        img.setAlignment(1);//居中显示

        //显示位置，根据需要调整
        img.setAbsolutePosition(100, height - 40);

        //显示为原条形码图片大小的比例，百分比
        img.scalePercent(30);

        contentByte.addImage(img);

        stamp.close();
        is.close();

        return file;
    }

}
