package com.controller;

import com.alibaba.fastjson.JSON;
import com.config.BaseController;
import com.config.ControllerInterface;
import com.jfinal.aop.Before;
import com.jfinal.aop.Clear;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.upload.UploadFile;
import com.model.Book;
import com.model.BookDetail;
import com.model.BookPlus;
import com.model.BookYubian;
import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException;
import com.service.*;
import com.tools.ISBNTools;
import com.tools.JwtUtils;
import com.utils.CommonUtils;
import com.utils.DateUtils;
import com.utils.ExcelUtil;
import com.utils.MarcUtil;
import com.validator.BookValidator;
import org.apache.commons.io.FileUtils;

import java.beans.IntrospectionException;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 图书操作
 * 2018-10-23
 */
@ControllerInterface(path="/bookyubian")
public class BookYubianController extends BaseController {

    BookYubianService yubianService = BookYubianService.me;

    BookTypeService bookTypeService= BookTypeService.me;

    DictService dictService = DictService.me;

    DictExtService dictExtService = DictExtService.me;



    public void list(){
        try{
            BookYubian bean = getBean(BookYubian.class,"bean");
            //根据时间排序 timesortd正序 timesorta倒序
            String timesortd = this.getPara("bean.timesortd");
            String timesorta = this.getPara("bean.timesorta");
            String bookstatus = getPara("bookstatus");
            Page<Record> page =  yubianService.paginate(this.getParaToInt("pageNumber"),this.getParaToInt("pageSize"),timesortd,timesorta,bean,  bookstatus);
            success(page);
        }catch(Exception e){
            e.printStackTrace();
            fail();
        }

    }



    public void upload() {
        try {
            String token = this.getPara("token");
            int operatorid = JwtUtils.validateJWTForUserId(token);
            if (operatorid == 0) {
                fail(3, "token错误");
                return;
            }
            int orgid = getParaToInt("orgid");
            Record orgRecord = Db.findById("t_org",orgid);
            SimpleDateFormat datesf = new SimpleDateFormat("yyyy-MM-dd");
            //List<String> booktypeList=bookTypeService.booktype();
            Map<String,Integer> dictmap = dictService.dictmap();

            List<Map<String,String>> errorDataList = new ArrayList<Map<String,String>>();
            UploadFile file =getFile();
            List<Map<String,String>> bookList= ExcelUtil.readExcel(new FileInputStream(file.getFile()));
            for (Map<String,String> bookMap : bookList) {
                try{
                    BookYubian book=new BookYubian();
                    book.setOrgid(orgid);

                    book.setIsbn(bookMap.get("ISBN"));
                    if (book.getIsbn()==null || book.getIsbn().trim().equals("")){
                        bookMap.put("未导入原因","ISBN不能为空!");
                        errorDataList.add(bookMap);
                        continue;
                    }
                    book.setTitle(bookMap.get("正题名"));
                    if (book.getTitle()==null || book.getTitle().trim().equals("")){
                        bookMap.put("未导入原因","正题名不能为空!");
                        errorDataList.add(bookMap);
                        continue;
                    }

                    book.setBltitle(bookMap.get("并列题名"));
                    book.setSubtitle(bookMap.get("副题名"));
                    book.setAuthor(bookMap.get("著者"));
                    if (book.getTitle()==null || book.getTitle().trim().equals("")){
                        bookMap.put("未导入原因","著者不能为空!");
                        errorDataList.add(bookMap);
                        continue;
                    }
                    book.setAuthorworkmodeid(dictmap.get(bookMap.get("著作方式")));
                    if (book.getAuthorworkmodeid()==null ){
                       book.setAuthorworkmodeid(7);//默认编著
                    }
                    book.setAuthorguobieid(dictmap.get(bookMap.get("国别或朝代")));
                    if (book.getAuthorguobieid() ==null){
                        book.setAuthorguobieid(20); //默认中
                    }

                    book.setPublisher(bookMap.get("出版社"));
                    book.setPublishaddress(bookMap.get("出版地"));
                    book.setPublishdate(bookMap.get("出版年月"));

                    book.setEdition(bookMap.get("版本版次"));

                    book.setPrice(new BigDecimal(bookMap.get("定价（元）")));
                    book.setSizeid(dictmap.get(bookMap.get("尺寸")));


                    book.setTypecode(bookMap.get("分类号"));
                    if (book.getTypecode()==null || book.getTypecode().trim().equals("") /*|| !booktypeList.contains(book.getTypecode())*/){
                        bookMap.put("未导入原因","分类号不正确!");
                        errorDataList.add(bookMap);
                        continue;
                    }
                    String typeid= book.getTypecode().substring(0,1);
                    book.setTypeid(typeid);//22大类ID

                    book.setJuanci(bookMap.get("卷次"));
                    book.setCeci(bookMap.get("册次"));
                    book.setBindingid(dictmap.get(bookMap.get("装订")));
                    if (book.getBindingid() ==null){
                        book.setBindingid(45);//默认平装
                    }
                    if (bookMap.get("页数")!=null && !bookMap.get("页数").equals("")){
                        book.setTotalpages(Integer.parseInt(bookMap.get("页数")));
                    }


                    book.setOperatorid(operatorid);
                    book.save();

                    Thread t = new Thread() {
                        public void run() {
                            String getUrl = PropKit.get("z3950url")+"/bookyubian/addBookYubian";
                            Map<String,String> param  = null;
                            try {
                                param = CommonUtils.convertBeanToMap(book);
                            } catch (IntrospectionException e) {
                                e.printStackTrace();
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                            }
                            if (CommonUtils.isNullOrEmpty(param)){
                                param = new HashMap();
                            }
                            param.put("org",orgRecord.getStr("orgname"));
                            try {
                                getUrl = CommonUtils.buildUrl(getUrl,param);
                            } catch (UnsupportedEncodingException e) {
                                e.printStackTrace();
                            }
                            String z3950str = CommonUtils.requestUrl(getUrl);
                            Map result = (Map)JSON.parse(z3950str);
                            //上传失败
                            if (!"200".equals(result.get("code")+"")){
                                logger.error("上传图书预编数据到z3950失败："+result.get("msg"));
                            }
                        }
                    };
                    t.start();
                }catch (Exception e){
                    if (e instanceof ParseException){
                        bookMap.put("未导入原因","日期格式不正确");
                    }else  if (e.getMessage().indexOf("Duplicate") !=-1){
                            bookMap.put("未导入原因","重复数据！");
                    }else{
                        bookMap.put("未导入原因",e.getMessage());
                    }
                    errorDataList.add(bookMap);
                }
            }
            String filename="";
            if (errorDataList.size()>0){
                filename="图书未导入列表"+ DateUtils.getNowTimeNo()+".xls";
                File targetFile =new File(getRequest().getRealPath("upload")+ File.separator+filename);
                ExcelUtil.writeExcel(targetFile,errorDataList,"图书未导入列表");
            }
            success(filename);
        } catch (Exception e) {
            e.printStackTrace();
            fail(0,e.getMessage());
        }
    }

    public void uploadMarc() {
        List errorDataList = new ArrayList();
        String filename = "importfail"+CommonUtils.getUUID()+".xls";
        File targetFile =new File(getRequest().getRealPath("upload")+"/"+filename);
        String token = this.getPara("token");
        int operatorid = JwtUtils.validateJWTForUserId(token);
        if (operatorid == 0) {
            fail(3, "token错误");
            return;
        }
        int orgid = getParaToInt("orgid");
        Record orgRecord = Db.findById("t_org",orgid);
        Map<String,String> dictExtMap = dictExtService.dictExtMap();
        UploadFile file =getFile();
        List<String> bookLineStrList = null;
        try {
            bookLineStrList = FileUtils.readLines(file.getFile(),"GBK");
        } catch (IOException e) {
            e.printStackTrace();
        }
        Map<String,Integer> guobieMap = dictService.dictnametokey(1);
        Map<String,Integer> workmodeidMap = dictService.dictnametokey(0);
        Map<String,Integer> sizeidMap = dictService.dictnametokey(3);
        Map<String,Integer> languageidMap = dictService.dictnametokey(4);
        Map<String,Integer> bindingidMap = dictService.dictnametokey(5);
        List<Record> expRecordList = Db.find("select CONCAT(fieldid,subfieldid) exp,sysfield formname from t_sysmkf where formname is not null");
        for (String book : bookLineStrList){
            BookYubian bookYubian = new BookYubian();
            try {
                List<Map<String,String>> list = MarcUtil.showMarc(book.getBytes("GBK"));
                Record marcRecord = MarcUtil.mapToRecord(list.get(0),expRecordList);
                marcRecord.set("totalpages",Integer.parseInt(marcRecord.getStr("totalpages").replace(",","")));
                bookYubian.put(marcRecord);

                if(CommonUtils.isNotNullOrNotEmpty(bookYubian.get("workmodeid"))) {
                    if(CommonUtils.isNullOrEmpty(workmodeidMap.get(bookYubian.get("workmodeid")))) {
                        String errorInfo = bookYubian.get("workmodeid");
                        bookYubian.put("errorInfo", errorInfo + "著作方式的值不正确");
                        throw new Exception();
                    }
                    int zzfsid = workmodeidMap.get(bookYubian.get("workmodeid"));
                    if (zzfsid == 0) {
                        String errorInfo = bookYubian.get("workmodeid");
                        bookYubian.put("errorInfo", errorInfo + "著作方式的值不正确");
                        throw new Exception();
                    } else {
                        bookYubian.set("workmodeid",zzfsid);
                    }
                }

                if(CommonUtils.isNotNullOrNotEmpty(bookYubian.get("guobie"))) {
                    if(CommonUtils.isNullOrEmpty(guobieMap.get(bookYubian.get("guobie")))) {
                        String errorInfo = bookYubian.get("guobie");
                        bookYubian.put("errorInfo", errorInfo + "国别的值不正确");
                        throw new Exception();
                    }
                    int zzfsid = guobieMap.get(bookYubian.get("guobie"));
                    if (zzfsid == 0) {
                        String errorInfo = bookYubian.get("guobie");
                        bookYubian.put("errorInfo", errorInfo + "国别的值不正确");
                        throw new Exception();
                    } else {
                        bookYubian.set("guobie",zzfsid);
                    }
                }

                if(CommonUtils.isNotNullOrNotEmpty(bookYubian.get("sizeid"))) {
                    if(CommonUtils.isNullOrEmpty(sizeidMap.get(bookYubian.get("sizeid")))) {
                        String errorInfo = bookYubian.get("sizeid");
                        bookYubian.put("errorInfo", errorInfo + "尺寸的值不正确");
                        throw new Exception();
                    }
                    int zzfsid = sizeidMap.get(bookYubian.get("sizeid"));
                    if (zzfsid == 0) {
                        String errorInfo = bookYubian.get("sizeid");
                        bookYubian.put("errorInfo", errorInfo + "尺寸的值不正确");
                        throw new Exception();
                    } else {
                        bookYubian.set("sizeid",zzfsid);
                    }
                }

                if(CommonUtils.isNotNullOrNotEmpty(bookYubian.get("languageid"))) {
                    if(CommonUtils.isNullOrEmpty(languageidMap.get(bookYubian.get("languageid")))) {
                        String errorInfo = bookYubian.get("languageid");
                        bookYubian.put("errorInfo", errorInfo + "语种的值不正确");
                        throw new Exception();
                    }
                    int zzfsid = languageidMap.get(bookYubian.get("languageid"));
                    if (zzfsid == 0) {
                        String errorInfo = bookYubian.get("languageid");
                        bookYubian.put("errorInfo", errorInfo + "语种的值不正确");
                        throw new Exception();
                    } else {
                        bookYubian.set("languageid",zzfsid);
                    }
                }

                if(CommonUtils.isNotNullOrNotEmpty(bookYubian.get("bindingid"))) {
                    if(CommonUtils.isNullOrEmpty(bindingidMap.get(bookYubian.get("bindingid")))) {
                        String errorInfo = bookYubian.get("bindingid");
                        bookYubian.put("errorInfo", errorInfo + "装订形式的值不正确");
                        throw new Exception();
                    }
                    int zzfsid = bindingidMap.get(bookYubian.get("bindingid"));
                    if (zzfsid == 0) {
                        String errorInfo = bookYubian.get("bindingid");
                        bookYubian.put("errorInfo", errorInfo + "装订形式的值不正确");
                        throw new Exception();
                    } else {
                        bookYubian.set("bindingid",zzfsid);
                    }
                }

                bookYubian = (BookYubian)CommonUtils.checkedAtImport(bookYubian,dictExtMap);
                if(CommonUtils.isNullOrEmpty(bookYubian.get("errorInfo"))) {
                    throw new Exception();
                }
                bookYubian.set("orgid",orgid);
                if(CommonUtils.isNullOrEmpty(bookYubian.getIsbn()) && CommonUtils.isNullOrEmpty(bookYubian.getTitle())) {
                    bookYubian.put("errorInfo", "ISBN或正题名不能为空");
                    throw new Exception();
                } else {
                    bookYubian.save();

                    BookYubian finalBookYubian = bookYubian;
                    Thread t = new Thread() {
                        public void run() {
                            String getUrl = PropKit.get("z3950url")+"/bookyubian/addBookYubian";
                            Map<String,String> param  = null;
                            try {
                                param = CommonUtils.convertBeanToMap(finalBookYubian);
                            } catch (IntrospectionException e) {
                                e.printStackTrace();
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                            }
                            if (CommonUtils.isNullOrEmpty(param)){
                                param = new HashMap();
                            }
                            param.put("org",orgRecord.getStr("orgname"));
                            try {
                                getUrl = CommonUtils.buildUrl(getUrl,param);
                            } catch (UnsupportedEncodingException e) {
                                e.printStackTrace();
                            }
                            String z3950str = CommonUtils.requestUrl(getUrl);
                            Map result = (Map)JSON.parse(z3950str);
                            //上传失败
                            if (!"200".equals(result.get("code")+"")){
                                logger.error("上传图书预编数据到z3950失败："+result.get("msg"));
                            }
                        }
                    };
                    t.start();


                }
            } catch (Exception e) {
                Map errorInfoMap = new LinkedHashMap();
                errorInfoMap.put("22大类","");
                errorInfoMap.put("分类号",bookYubian.get("typecode"));
                errorInfoMap.put("书次号",bookYubian.get("shucihao"));
                errorInfoMap.put("复本数","");
                errorInfoMap.put("ISBN",bookYubian.get("ISBN"));
                errorInfoMap.put("正题名",bookYubian.get("title"));
                errorInfoMap.put("出版社",bookYubian.get("publisher"));
                errorInfoMap.put("主题词",bookYubian.get("keyword"));
                errorInfoMap.put("版本版次",bookYubian.get("version"));
                errorInfoMap.put("作者",bookYubian.get("author"));
                errorInfoMap.put("国别或朝代",bookYubian.get("guobieid"));
                errorInfoMap.put("索书号",bookYubian.get("bookno"));
                errorInfoMap.put("出版地",bookYubian.get("publishaddress"));
                errorInfoMap.put("定价",bookYubian.get("price"));
                errorInfoMap.put("图书新增来源","");
                errorInfoMap.put("错误原因",bookYubian.get("errorInfo"));
                errorDataList.add(errorInfoMap);
            }
        }
        if(errorDataList.size() > 0) {
            ExcelUtil.writeExcel(targetFile, errorDataList, "图书未导入列表");
            success(filename);
        }else {
            success("导入成功");
        }
    }

    public void delete(){
        try{

            String[] bookIDList= getParaValues("bookIDList[]");
            for (String id : bookIDList){
                yubianService.deleteByID(Integer.parseInt(id));
            }
            success();
        }catch (Exception e){
            fail();
        }
    }


    public void findBookInfo(){
        success(yubianService.findBookYubianByID(getParaToInt("id")));
    }

    public void saveOrUpdate(){
        try{
            BookYubian bookYubian=getBean(BookYubian.class,"bean");
            if (bookYubian.getTypeid() ==null){
                bookYubian.setTypeid(bookYubian.getTypecode().substring(0,1));
            }
            yubianService.saveOrUpdate(bookYubian);

            Record orgRecord = Db.findById("t_org",bookYubian.getOrgid());
            Thread t = new Thread() {
                public void run() {
                    String getUrl = PropKit.get("z3950url")+"/bookyubian/addBookYubian";
                    Map<String,String> param  = null;
                    try {
                        param = CommonUtils.convertBeanToMap(bookYubian);
                    } catch (IntrospectionException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                    if (CommonUtils.isNullOrEmpty(param)){
                        param = new HashMap();
                    }
                    param.put("org",orgRecord.getStr("orgname"));
                    try {
                        getUrl = CommonUtils.buildUrl(getUrl,param);
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                    String z3950str = CommonUtils.requestUrl(getUrl);
                    Map result = (Map)JSON.parse(z3950str);
                    //上传失败
                    if (!"200".equals(result.get("code")+"")){
                        logger.error("上传图书预编数据到z3950失败："+result.get("msg"));
                    }
                }
            };
            t.start();

            success();
        }catch (Exception e){
            fail();
        }
    }


}
