/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.triz.util;

import com.lowagie.text.BadElementException;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.PageSize;
import com.lowagie.text.Paragraph;
import com.triz.trizservice.modeles.AnneeFiscale;
import com.triz.trizservice.modeles.Etablissement;
import com.triz.trizservice.modeles.ServiceIncrementation;
import com.triz.trizservice.modeles.ServiceUser;
import com.triz.trizservice.modeles.ServiceHistoriqueManipulation;
import com.triz.trizservice.modeles.StockTypeDestinataire;
import com.triz.trizservice.service.TransactionService;
import java.io.ByteArrayInputStream;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.IOUtils;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Service;

/**
 *
 * @author abderrahim.TOUAIBIA
 */
@Service()
public class UtilContext {

    private String titre;
    private String db_URL;
    private String url = "jdbc:sqlserver://localhost:1433;databaseName=";
    private String dossierSauvegarde = "sauvegarde";
    private ServiceHistoriqueManipulation historiqueManipulation;

    @Autowired
    private TransactionService service;

    public String getTitre() {
        return titre;
    }

    public void setTitre(String titre) {
        this.titre = titre;
    }

    public ServiceUser getCurrentUser() {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (user != null) {
            return service.getUserById(user.getUsername());
        }
        return null;
    }

    public String changeStatutLigneUser() {
        ServiceUser user = getCurrentUser();
        service.saveUser(user);
        return UtilURL.DISTRIBUTION_URL;
    }

    public static boolean isInternetAvailable() throws IOException {
        return isHostAvailable("google.com");
    }

    private static boolean isHostAvailable(String hostName) throws IOException {
        try (Socket socket = new Socket()) {
            int port = 80;
            InetSocketAddress socketAddress = new InetSocketAddress(hostName, port);
            socket.connect(socketAddress, 3000);

            return true;
        } catch (UnknownHostException unknownHost) {
            return false;
        }
    }

    
    public static ServiceIncrementation remiseAZeroIncr(ServiceIncrementation incr) {
        System.out.println(" remiseAZeroIncr ");
        Date date = new Date();
        incr.setDateMois(date);

        return incr;
    }

    public static ServiceIncrementation remiseAZeroIncrAnnee(ServiceIncrementation incr) {
        System.out.println(" remiseAZeroIncr ");
        Date date = new Date();
        incr.setDateMois(date);
        return incr;
    }

    public static ServiceIncrementation remiseAZeroIncrMois(ServiceIncrementation incr) {
        System.out.println(" remiseAZeroIncrmois ");
        Date date = new Date();
        incr.setDateMois(date);
        return incr;
    }

    public String userID() {
        ServiceUser user = getCurrentUser();
        return user.getUserid();
    }

    public static String formatDateNew(Date date) {
        if (date == null) {
            return "";
        }
        SimpleDateFormat simpleDate = new SimpleDateFormat("dd-MM-yyyy");
        return simpleDate.format(date);
    }

    public static String dateFormatDayMonthYearAndTime(Date date) {
        if (date == null) {
            return "";
        }
        SimpleDateFormat simpleDate = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
        return simpleDate.format(date);
    }

    public void preProcessPDF(Object document) throws IOException, BadElementException, DocumentException {

        System.out.println("Hello, my name is preProcessPDF");

        Document pdf = (Document) document;
        pdf.open();
        pdf.setPageSize(PageSize.A4);
        pdf.add(new Paragraph("                         " + titre + "\n\n\n"));
    }

    public void preProcessPDF1(String titre1, Object document) throws IOException, BadElementException, DocumentException {

        Document pdf = (Document) document;
        pdf.open();
        pdf.setPageSize(PageSize.A4);
        pdf.add(new Paragraph("                         " + titre1 + "\n\n\n"));
    }

    public void postProcessXLS(Object document) throws DocumentException, FileNotFoundException, IOException {

        XSSFWorkbook wb = (XSSFWorkbook) document;
        XSSFSheet sheet = wb.getSheetAt(0);
        //sheet.autoSizeColumn(100);
        sheet.shiftRows(0, sheet.getLastRowNum(), 2);
        XSSFRow row = sheet.createRow((short) 0);
        XSSFCell cell = row.createCell(2);
        cell.setCellValue(titre);
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 2, 8));
        XSSFCellStyle cellStyleDate = (XSSFCellStyle) sheet.getWorkbook().createCellStyle();
        XSSFCellStyle cellStyleHeur = (XSSFCellStyle) sheet.getWorkbook().createCellStyle();
        XSSFCellStyle cellStyleMontant = (XSSFCellStyle) sheet.getWorkbook().createCellStyle();
        XSSFCellStyle cellStyleInt = (XSSFCellStyle) sheet.getWorkbook().createCellStyle();

        CreationHelper createHelper = sheet.getWorkbook().getCreationHelper();
        cellStyleDate.setDataFormat(
                createHelper.createDataFormat().getFormat("dd/MM/yyyy"));
        cellStyleHeur.setDataFormat(
                createHelper.createDataFormat().getFormat("hh:mm:ss"));

        cellStyleMontant.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00"));

        cellStyleInt.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0"));

        for (int ligne = 0; ligne <= sheet.getLastRowNum(); ligne++) {
            row = sheet.getRow(ligne);
            if (row == null) {
                continue;
            }
            for (int colon = 0; colon <= row.getPhysicalNumberOfCells(); colon++) {
                cell = row.getCell(colon);
                if (cell == null) {
                    continue;
                }
                String mot = "";
                if (cell.getCellType() == CellType.STRING) {
                    mot = cell.getStringCellValue();
                }
                if (cell.getCellType() == CellType.NUMERIC) {
                    mot = cell.getNumericCellValue() + "";
                }
                mot = mot.replace(" ", "");
                mot = mot.replace(",", ".");

                try {
                    SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM-dd");
                    cell.setCellValue(simpleDate.parse(mot));
                    cell.setCellStyle(cellStyleDate);
                    continue;

                } catch (Exception e) {

                }

                try {
                    SimpleDateFormat simpleDate = new SimpleDateFormat("hh:mm:ss");
                    cell.setCellValue(simpleDate.parse(mot));
                    cell.setCellStyle(cellStyleHeur);
                    continue;

                } catch (Exception e) {

                }

                if (!mot.contains(".")) {
                    if (mot.length() > 8) {
                        continue;
                    }
                }

                try {
                    Integer numbre = Integer.valueOf(mot);
                    cell.setCellValue(numbre);
                    cell.setCellStyle(cellStyleInt);
                    continue;

                } catch (Exception e) {

                }
                try {
                    Float numbre = Float.valueOf(mot);
                    cell.setCellValue(numbre);
                    cell.setCellStyle(cellStyleMontant);
                    continue;

                } catch (Exception e) {

                }
                try {
                    Double numbre = Double.valueOf(mot);
                    cell.setCellValue(numbre);
                    cell.setCellStyle(cellStyleMontant);
                    continue;

                } catch (Exception e) {

                }
            }
        }
    }

    public String getConcatinationOfTitre(String c1, String c2, String c3, String c4, String c5) {
        return c1 + c2 + c3 + c4 + c5;
    }

    public String getConcatinationOfTitre(String c1, String c2, String c3, String c4, String c5, String c6) {
        return c1 + c2 + c3 + c4 + c5 + c6;
    }

    public String getConcatinationOfTitre(String c1, String c2, String c3, String c4, String c5, String c6, String c7) {
        return c1 + c2 + c3 + c4 + c5 + c6 + c7;
    }

    public String getConcatinationOfTitre(String c1, String c2, String c3, String c4, String c5, String c6, String c7, String c8) {
        return c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8;
    }

    public String getConcatinationOfTitreDate(String c1, String c2, Date c3, Date c4, String c5, String c6) {
        return c1 + c2 + formatDate(c3) + "  au   " + this.formatDate(c4) + c5 + c6;
    }

    public String formatDate(Date date) {
        SimpleDateFormat simpleDate = new SimpleDateFormat("dd-MM-yyyy");
        return simpleDate.format(date);
    }

    public StreamedContent getFileContentDistribution() throws IOException {
        db_URL = new UtilGetParametre().getPropertyByKey(UtilGetParametre.TRIZDISTRIBUTION_BD_URL);
        return getFileContent(typeContenentZip, createBakFile());
    }

    public StreamedContent getFileContentStock() throws IOException {
        db_URL = new UtilGetParametre().getPropertyByKey(UtilGetParametre.TRIZSTOCK_BD_URL);
        return getFileContent(typeContenentZip, createBakFile());
    }

    private String createBakFile() {

        String db = db_URL.substring(url.length());
        System.out.println("bdDistribution :" + db);

        String bakFileName = db + "_" + dateTimeFormat(new Date());
        String bakFile = UtilFile.getDirectoryName(dossierSauvegarde) + "/" + bakFileName + ".bak";
        System.out.println("bakFile :" + bakFile);
        int processComplete = service.genererBDD(bakFile, db);
        System.out.println("processComplete :" + processComplete);

        File file = new File(bakFile);

        if (file.exists()) {
            try {
                bakFile = createZipFile(bakFile, bakFileName, dossierSauvegarde);
            } catch (Exception e) {

            }
        }
        return bakFile;
    }

    public String createZipFile(String bakFile, String bakFileName, String folder_name_origine) throws IOException {
        System.out.println("createZipFile"+ bakFile);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyMMddHHmm");
        String fileOutput_name = bakFileName + ".zip";

        File uploadedDer = new File(UtilFile.getDirectoryName(folder_name_origine));
        if (!uploadedDer.exists()) {
            uploadedDer.mkdirs();
        }
        File fileOutput = new File(UtilFile.getFilePath(folder_name_origine, fileOutput_name));
        fileOutput.createNewFile();

        List<File> listeFile_path = new ArrayList<>();
        listeFile_path.add(new File(bakFile));

        final File firstfile = new File(UtilFile.getDirectoryName(folder_name_origine));
        if (firstfile.exists()) {
            ZipUtils zipfl = new ZipUtils();
            try {
                zipfl.zipFiles(listeFile_path, firstfile, fileOutput);
            } catch (IOException ex) {
                Logger.getLogger(UtilContext.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        System.out.println("fileOutput.getPath():" + fileOutput.getPath());
        return fileOutput.getPath();
    }
    
    String typeContenentBAK = "application/bak";
    String typeContenentZip = "application/zip";
    public StreamedContent getFileContent(String typeContenent, String pathGet) throws IOException {
        
        System.out.println("get file content --starts");
        File file = new File(pathGet);

        if (file.exists()) {
            System.out.println("File exsits --- " + file);
            System.out.println("File name --- " + file.getName());
            byte contents[] = IOUtils.toByteArray(new FileInputStream(file));
            DefaultStreamedContent content = DefaultStreamedContent.builder().name(file.getName()).contentType("application/bak").stream(() -> new ByteArrayInputStream(contents)).build();

            System.out.println("File content " + content);

            return content;
        } else {
            System.out.println("File Not exsits --- ");
            return null;
        }
    }

    public boolean backupDB(String path) {
        Process runtimeProcess;
        try {
            runtimeProcess = Runtime.getRuntime().exec("cmd /c " + path);
            int processComplete = runtimeProcess.waitFor();

            if (processComplete == 0) {
                System.out.println("Backup created successfully");
                return true;
            } else {
                System.out.println("Could not create the backup");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return false;
    }

    private String pathBat() {

        String db = db_URL.substring(url.length());
        System.out.println("bdDistribution :" + db);
        String bakFile = UtilFile.getDirectoryName(dossierSauvegarde) + "/" + db + "_" + dateTimeFormat(new Date()) + ".bak";
        System.out.println("bakFile :" + bakFile);
        String path = "osql.exe -E -Q \"BACKUP DATABASE " + db + " TO DISK='" + bakFile + "' WITH FORMAT\"";
        System.out.println("path :" + path);
        boolean isBackup = backupDB(path);

        System.out.println("BackupStatus :" + isBackup);
        if (!isBackup) {
            return null;
        }
        return bakFile;
    }

    private String dateTimeFormat(Date date) {
        SimpleDateFormat simpleDate = new SimpleDateFormat("dd-MM-yyyy_HH_mm_ss");
        return simpleDate.format(date);
    }

    public String getNomEtablissementFromProperties() {
        if (UtilGetParametre.TRIZDISTRIBUTION_ETABLISSEMENT_NOM != null) {
            return UtilGetParametre.TRIZDISTRIBUTION_ETABLISSEMENT_NOM;
        }
        return "";
    }

    public void saveNewManipulation(String nomTable, String idLigne, String typeManipulation, Date date, Date heur, ServiceUser user, Double oldValour, Double newValeur) {
        historiqueManipulation = new ServiceHistoriqueManipulation();
        historiqueManipulation.setFkManipulateur(user);
        historiqueManipulation.setIdLigne(idLigne);
        historiqueManipulation.setNomTable(nomTable);
        historiqueManipulation.setTypeManipumation(typeManipulation);
        historiqueManipulation.setOldValeur(oldValour.floatValue());
        historiqueManipulation.setNewValeur(newValeur.floatValue());
        historiqueManipulation.setDateManipulation(new Date());
        historiqueManipulation.setHeurManipulation(new Date());
        service.save(historiqueManipulation);
    }

    public String formatAnneeForCodage(Date date) {
        SimpleDateFormat simpleDate = new SimpleDateFormat("yy");
        return simpleDate.format(date);
    }
    
    public boolean isOnLigneUser() {
        ServiceUser user = getCurrentUser();
        return false;
    }
    
     public Etablissement getCurrentEtablissement() {
        System.out.println("UtilURLStock.getStock_CODE_SYSTEM() " + UtilURL.getStock_CODE_SYSTEM());
        Etablissement etablissemnt = service.getEtablissementById(UtilURL.getStock_CODE_SYSTEM());
        if (etablissemnt != null) {
            return etablissemnt;
        }
        return null;
    }
     
      public AnneeFiscale getCurrentAnneeFiscal() {
        System.out.println("UtilURLStock.getStock_CODE_SYSTEM() " + UtilURL.getStock_CODE_SYSTEM());
        AnneeFiscale annee = service.getAnneFiscalByEtablissementByActif(getCurrentEtablissement());
        if (annee != null) {
            return annee;
        }
        return null;
    }
      
       public boolean canChangeEtablissement() {
        ServiceUser user = getCurrentUser();
        List<Etablissement> listeEtablissement = service.getAllStockEtablissementFromUsersEtablissementByUser(user);
        if (listeEtablissement != null) {
            if (!listeEtablissement.isEmpty()) {
                if (listeEtablissement.size() > 1) {
                    return true;
                }
                return false;
            }
            return false;
        }

        return false;
    }
}
