/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.arrebol.taxiservicios.beans.catalog;

/*import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;*/
import com.arrebol.taxiservicios.beans.Datatable;
import com.arrebol.taxiservicios.beans.TaxiGenericBean;
import com.arrebol.taxiservicios.controller.catalog.DocumentoController;
import com.arrebol.taxiservicios.controller.catalog.LocationController;
import com.arrebol.taxiservicios.controller.catalog.RegimenFiscalController;
import com.arrebol.taxiservicios.controller.system.UserController;
import com.arrebol.taxiservicios.model.catalog.Brand;
import com.arrebol.taxiservicios.model.catalog.Location;
import com.arrebol.taxiservicios.model.catalog.RegimenFiscal;
import com.arrebol.taxiservicios.model.core.User;
import com.arrebol.taxiservicios.model.catalog.UserLocation;
import com.arrebol.taxiservicios.controller.catalog.UserLocationController;
import com.arrebol.taxiservicios.model.catalog.LocationPaquetes;
import com.arrebol.taxiservicios.model.catalog.Paquetes;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.event.ReorderEvent;
import org.primefaces.event.RowEditEvent;
import org.primefaces.model.UploadedFile;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 *
 * @author oscarvargas
 */
@Named("locationManager")
@ViewScoped
public class LocationManager extends TaxiGenericBean implements Serializable, Datatable {

    @Override
    public void editRow(RowEditEvent event) {

    }

    @Override
    public void onRowCancel(RowEditEvent event) {
        showMessage(FacesMessage.SEVERITY_INFO, "Edición Cancelada", ((Brand) event.getObject()).getName());
    }

    @Override
    public void onRowReorder(ReorderEvent event) {
        showMessage(FacesMessage.SEVERITY_INFO, "Registro Movido", "De columna: " + (event.getFromIndex() + 1) + " a columna: " + (event.getToIndex() + 1));
    }

    @Override
    public void addRow() {
        Location locationObj = new Location();

        locationObj.setId(getSelectedLocation() != null ? getSelectedLocation().getId() : null);
        locationObj.setName(name);
        locationObj.setAddress(address);
        locationObj.setMunicipality(municipality);
        locationObj.setState(state);
        locationObj.setBusinessName(businessName);
        locationObj.setGerente(gerente);
        locationObj.setMail(mail);
        locationObj.setPostalCode(postalCode);
        locationObj.setSuburb(suburb);
        locationObj.setTaxRegime(new RegimenFiscal(taxRegime));
        locationObj.setPhone(phone);
        locationObj.setRfc(rfc);
        locationObj.setCompleteAddress(address + " " + suburb + " " + municipality + " " + state + " " + postalCode);

        controller.addLocation(locationObj, getLoggedUser().getId());
        setLocation(getController().fillLocationDatatable());
        clearInfo();
        FacesMessage msg = new FacesMessage("Nueva locación", "Se agregó correctamente");
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    public void updateInfo() {
        setName(getSelectedLocation().getName());
        setGerente(getSelectedLocation().getGerente() != null ? getSelectedLocation().getGerente() : null);
        setBusinessName(getSelectedLocation().getBusinessName() != null ? getSelectedLocation().getBusinessName() : null);
        setRfc(getSelectedLocation().getRfc() != null ? getSelectedLocation().getRfc() : null);
        setMail(getSelectedLocation().getMail() != null ? getSelectedLocation().getMail() : null);
        setAddress(getSelectedLocation().getAddress() != null ? getSelectedLocation().getAddress() : null);
        setSuburb(getSelectedLocation().getSuburb() != null ? getSelectedLocation().getSuburb() : null);
        setState(getSelectedLocation().getState() != null ? getSelectedLocation().getState() : null);
        setMunicipality(getSelectedLocation().getMunicipality() != null ? getSelectedLocation().getMunicipality() : null);
        setPostalCode(getSelectedLocation().getPostalCode() != null ? getSelectedLocation().getPostalCode() : null);
        setPhone(getSelectedLocation().getPhone() != null ? getSelectedLocation().getPhone() : null);
        setTaxRegime(getSelectedLocation().getTaxRegime() != null ? getSelectedLocation().getTaxRegime().getId() : null);        
    }

    public void updateLocationLogo() {
        setLocationLogo(getSelectedLocation());

    }

    public void updateInfoPrinter() {
        setPrinterName(getSelectedLocation().getPrinter() != null ? getSelectedLocation().getPrinter() : null);
    }

    public void clearInfo() {
        setName(null);
        setGerente(null);
        setBusinessName(null);
        setRfc(null);
        setMail(null);
        setAddress(null);
        setSuburb(null);
        setState(null);
        setMunicipality(null);
        setPostalCode(null);
        setPhone(null);
        setTaxRegime(null);
        setSelectedLocation(null);
        setPrinterName(null);
        setMaxPerson(null);
        setSelectIdPaquete(null);
    }

    @Override
    public void deleteRow() {
        controller.delete(selectedLocation);
        location.remove(selectedLocation);
        selectedLocation = null;
        showMessage(FacesMessage.SEVERITY_INFO, "Locación eliminada", "Se eliminó correctamente.");
    }

    public void saveCertificate() {
        isPeronsaFisica();

        if (getCertificate() != null && getCertificateKey() != null) {
            FacesMessage message = new FacesMessage("Successful", getCertificate().getFileName() + " is uploaded. "
                    + getCertificateKey().getFileName() + " is uploaded. ");
            FacesContext.getCurrentInstance().addMessage(null, message);

            getSelectedLocation().setCertificatePassword(getCertificatePassWord());
        }
        try {
            getController().addLocationCertificate(
                    getBundlePropertyFile().getString("aws.access.key"),
                    getBundlePropertyFile().getString("aws.secret.access.key"),
                    getBundlePropertyFile().getString("aws.region"),
                    getBundlePropertyFile().getString("aws.bucket"), getCertificate(), getCertificateKey(),
                    getCertificateInputStream(), getKeyInputStream(),
                    "",
                    getSelectedLocation(), getLoggedUser().getId());

        } catch (IOException ex) {
            logger.error("Error al guardar el certificado", ex);
            //Logger.getLogger(LocationManager.class.getName()).log(Level.SEVERE, null, ex);
        }

        FacesMessage msg = new FacesMessage("Certificados guardados", "Se agregaron correctamente los certificados");
        FacesContext.getCurrentInstance().addMessage(null, msg);

    }

    public void butonTest() {

        showMessage(FacesMessage.SEVERITY_INFO, "Certificado seleccionado", "Certificado seleccionado para almacenamiento");
    }

    public void uploadCertificate(FileUploadEvent event) throws IOException {

        setCertificate(event.getFile());
        setCertificateInputStream(event.getFile().getInputstream());
        showMessage(FacesMessage.SEVERITY_INFO, "Certificado seleccionado", "Certificado seleccionado para almacenamiento");
    }

    public void uploadCertificateKey(FileUploadEvent event) throws IOException {
        setCertificateKey(event.getFile());
        setKeyInputStream(event.getFile().getInputstream());
        showMessage(FacesMessage.SEVERITY_INFO, "Llave seleccionada", "Llave seleccionada para almacenamiento");
    }

    private void printerListInit() {
        PrintService[] ps = PrintServiceLookup.lookupPrintServices(null, null);
        try {
            for (PrintService p : ps) {
                getPrinterList().add(p.getName());
            }
        } catch (NullPointerException ex) {
            logger.error("No se encontraron impresoras", ex);
        }

    }

    public void addPrinter() {
        Location locationObj = new Location();
        locationObj.setId(getSelectedLocation() != null ? getSelectedLocation().getId() : null);
        FacesMessage msg;
        if (locationObj.getId() != null) {
            locationObj.setPrinter(getPrinterName());
            controller.updatePrinter(locationObj, getLoggedUser().getId());
            msg = new FacesMessage("Impresora asignada", "Se asignó la impresora correctamente ");
        } else {
            msg = new FacesMessage("Error", "No se encontró la impresora");
        }
        setLocation(getController().fillLocationDatatable());
        clearInfo();
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    public void clearselected() {
        setSelectedLocation(null);
    }

    public void findUserLocation() {
        setUserLocationController(new UserLocationController());
        setListUserLocation(getUserLocationController().fillAllUserLocationByLocation(getSelectedLocation()));
    }

    /*
    public void addUserLocation() {
        logger.info("addUserLocation");
        try {
            //Se valida si el usuario ya tiene un registro asociado con la locación 
            Boolean valUsr = true;
            for (UserLocation usLo : getListUserLocation()) {
                if (usLo.getLocation().getId().equals(getSelectedLocation().getId()) && usLo.getUser().getId().equals(getSelectedUse())) {
                    valUsr = false;
                }
            }
            
            if (valUsr) {
                setUserController(new UserController());
                setUserLocationController(new UserLocationController());
                // Buscamos al usuario seleccionado
                User us = getUserController().getById(getSelectedUse());
                // se crea un nuevo registro en UserLocation
                UserLocation usLo = new UserLocation();
                usLo.setLocation(getSelectedLocation());
                usLo.setUser(us);
                usLo.setPagoAutomatico(0);
                usLo.setEstatusActivo(GenericEnumType.ENABLED);
                getUserLocationController().addUserLocation(usLo, getLoggedUser(), true);
                //Actualizó los datos de la tabla 
                setSelectedUse(null);
                setListUserLocation(getUserLocationController().fillAllUserLocationByLocation(getSelectedLocation()));
                showMessage(FacesMessage.SEVERITY_INFO, "Se agregó el usuario", "Se agregó el usuario correctamente ");
                logger.info("Se agregó el usuario correctamente");
            } else {
                showMessage(FacesMessage.SEVERITY_ERROR, "Error", "El usuario seleccionado ya está asociado con la locación");
            }

        } catch (Exception e) {
            showMessage(FacesMessage.SEVERITY_INFO, "Error", "Ocurrió un erro al agregar el usuario a la locación ");
            logger.error("Ocurrió un erro al agregar el usuario a la locación", e);
        }
    }
     */
 /*
    public void deleteUserLocation() {
        logger.info("deleteUserLocation");
        try {
            setUserLocationController(new UserLocationController());
            getSelectedLocation().setEstatusActivo(GenericEnumType.DISABLED);
            getUserLocationController().addUserLocation(getSelectedLocation(), getLoggedUser(), true);
            showMessage(FacesMessage.SEVERITY_INFO, "Usuario eliminado", "Se eliminó el usuario de la ocasión");
            logger.info("Usuario eliminado ");
        } catch (Exception e) {
            showMessage(FacesMessage.SEVERITY_INFO, "Error", "Ocurrió un error a eliminar el usuario de la locación");
            logger.error("Ocurrió un error a eliminar el usuario de la locación", e);
        }

    }
     */
    private Date fechaMasDias(Date fecha, Integer dias) {
        // Convertir la fecha proporcionada a un objeto ZonedDateTime
        ZonedDateTime zonedDateTime = fecha.toInstant().atZone(ZoneId.systemDefault());
        // Sumar los días al objeto ZonedDateTime
        ZonedDateTime nuevaFecha = zonedDateTime.plusDays(dias);
        // Convertir el resultado nuevamente a un objeto Date
        return Date.from(nuevaFecha.toInstant());
    }

    public void subirLogo() throws IOException {
        logger.info("subirLogo");
        try {
            if (file != null) {
                try {
                    String extencion = file.getFileName();
                    String[] subString = extencion.split("\\.", 2);

                    String fileName = "logo." + subString[1];
                    InputStream inputStream = file.getInputstream();
                    OutputStream outputStream = new FileOutputStream(fileName);

                    int bytesRead;
                    byte[] buffer = new byte[8192];

                    while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
                        outputStream.write(buffer, 0, bytesRead);
                    }

                    outputStream.flush();
                    outputStream.close();
                    inputStream.close();
                    File xmlSubir = new File(fileName);
                    if (xmlSubir.exists()) {
                        boolean eliminado = xmlSubir.delete();
                        if (eliminado) {
                            System.out.println("Archivo eliminado correctamente");
                        } else {
                            System.out.println("No se ha podido eliminar el archivo");
                        }
                    } else {
                        System.out.println("El archivo no existe");
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {

        }
    }

    public void selectDemo() {
        if (getPackDemo()) {
            setIdPaquete(null);
        }
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Location> getLocation() {
        return location;
    }

    public void setLocation(List<Location> location) {
        this.location = location;
    }

    public Location getSelectedLocation() {
        return selectedLocation;
    }

    public void setSelectedLocation(Location selectedLocation) {
        this.selectedLocation = selectedLocation;
    }

    public LocationController getController() {
        return controller;
    }

    public void setController(LocationController controller) {
        this.controller = controller;
    }

    public String getGerente() {
        return gerente;
    }

    public void setGerente(String gerente) {
        this.gerente = gerente;
    }

    public String getBusinessName() {
        return businessName;
    }

    public void setBusinessName(String businessName) {
        this.businessName = businessName;
    }

    public String getRfc() {
        return rfc;
    }

    public void setRfc(String rfc) {
        this.rfc = rfc;
    }

    public String getMail() {
        return mail;
    }

    public void setMail(String mail) {
        this.mail = mail;
    }

    public String getTaxRegime() {
        return taxRegime;
    }

    public void setTaxRegime(String taxRegime) {
        this.taxRegime = taxRegime;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getSuburb() {
        return suburb;
    }

    public void setSuburb(String suburb) {
        this.suburb = suburb;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getMunicipality() {
        return municipality;
    }

    public void setMunicipality(String municipality) {
        this.municipality = municipality;
    }

    public String getPostalCode() {
        return postalCode;
    }

    public void setPostalCode(String postalCode) {
        this.postalCode = postalCode;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public RegimenFiscalController getRegimenFiscalController() {
        return regimenFiscalController;
    }

    public void setRegimenFiscalController(RegimenFiscalController regimenFiscalController) {
        this.regimenFiscalController = regimenFiscalController;
    }

    public List<RegimenFiscal> getRegimenFiscal() {
        return regimenFiscal;
    }

    public void setRegimenFiscal(List<RegimenFiscal> regimenFiscal) {
        this.regimenFiscal = regimenFiscal;
    }

    public UploadedFile getCertificate() {
        return certificate;
    }

    public void setCertificate(UploadedFile certificate) {
        this.certificate = certificate;
    }

    public UploadedFile getCertificateKey() {
        return certificateKey;
    }

    public void setCertificateKey(UploadedFile certificateKey) {
        this.certificateKey = certificateKey;
    }

    public void setCertificateInputStream(InputStream certificateInputStream) {
        this.certificateInputStream = certificateInputStream;
    }

    public InputStream getCertificateInputStream() {
        return certificateInputStream;
    }

    public InputStream getKeyInputStream() {
        return keyInputStream;
    }

    public void setKeyInputStream(InputStream keyInputStream) {
        this.keyInputStream = keyInputStream;
    }

    public String getCertificatePassWord() {
        return certificatePassWord;
    }

    public void setCertificatePassWord(String certificatePassWord) {
        this.certificatePassWord = certificatePassWord;
    }

    public boolean isPeronsaFisica() {
        return peronsaFisica;
    }

    public void setPeronsaFisica(boolean peronsaFisica) {
        this.peronsaFisica = peronsaFisica;
    }

    public String getPrinterName() {
        return printerName;
    }

    public void setPrinterName(String printerName) {
        this.printerName = printerName;
    }

    public List<String> getPrinterList() {
        return printerList;
    }

    public void setPrinterList(List<String> printerList) {
        this.printerList = printerList;
    }

    public Integer getMaxPerson() {
        return maxPerson;
    }

    public void setMaxPerson(Integer maxPerson) {
        this.maxPerson = maxPerson;
    }

    public UserController getUserController() {
        return userController;
    }

    public void setUserController(UserController userController) {
        this.userController = userController;
    }

    public List<User> getListUser() {
        return listUser;
    }

    public void setListUser(List<User> listUser) {
        this.listUser = listUser;
    }

    public String getSelectedUse() {
        return selectedUse;
    }

    public void setSelectedUse(String selectedUse) {
        this.selectedUse = selectedUse;
    }

    public List<UserLocation> getListUserLocation() {
        return listUserLocation;
    }

    public void setListUserLocation(List<UserLocation> listUserLocation) {
        this.listUserLocation = listUserLocation;
    }

    public UserLocation getSelectedUserLocation() {
        return selectedUserLocation;
    }

    public void setSelectedUserLocation(UserLocation selectedUserLocation) {
        this.selectedUserLocation = selectedUserLocation;
    }

    public UserLocationController getUserLocationController() {
        return userLocationController;
    }

    public void setUserLocationController(UserLocationController userLocationController) {
        this.userLocationController = userLocationController;
    }

    public List<LocationPaquetes> getListLocationPaquetes() {
        return listLocationPaquetes;
    }

    public void setListLocationPaquetes(List<LocationPaquetes> listLocationPaquetes) {
        this.listLocationPaquetes = listLocationPaquetes;
    }

    public List<Paquetes> getListPaquetes() {
        return listPaquetes;
    }

    public void setListPaquetes(List<Paquetes> listPaquetes) {
        this.listPaquetes = listPaquetes;
    }

    public String getIdPaquete() {
        return idPaquete;
    }

    public void setIdPaquete(String idPaquete) {
        this.idPaquete = idPaquete;
    }

    public LocationPaquetes getSelectLocationPaquetes() {
        return selectLocationPaquetes;
    }

    public void setSelectLocationPaquetes(LocationPaquetes selectLocationPaquetes) {
        this.selectLocationPaquetes = selectLocationPaquetes;
    }

    public Boolean getPackDemo() {
        return packDemo;
    }

    public void setPackDemo(Boolean packDemo) {
        this.packDemo = packDemo;
    }

    public String getSelectIdPaquete() {
        return selectIdPaquete;
    }

    public void setSelectIdPaquete(String selectIdPaquete) {
        this.selectIdPaquete = selectIdPaquete;
    }

    public UploadedFile getFile() {
        return file;
    }

    public void setFile(UploadedFile file) {
        this.file = file;
    }

    public DocumentoController getControladorDocumento() {
        return controladorDocumento;
    }

    public void setControladorDocumento(DocumentoController controladorDocumento) {
        this.controladorDocumento = controladorDocumento;
    }

    public Location getLocationLogo() {
        return locationLogo;
    }

    public void setLocationLogo(Location locationLogo) {
        this.locationLogo = locationLogo;
    }

    @PostConstruct
    public void init() {
        loadBundlePropertyFile();
        controller = new LocationController();
        setRegimenFiscalController(new RegimenFiscalController());
        setRegimenFiscal(getRegimenFiscalController().fillRegimenFiscalDatatable());
        setPrinterList(new ArrayList<>());
        location = controller.fillLocationDatatable();
        printerListInit();
    }

    final Logger logger = LogManager.getLogger(RegimenFiscalController.class);
    private static final long serialVersionUID = -5450130814186193205L;

    private List<Location> location;
    private Location selectedLocation;

    private RegimenFiscalController regimenFiscalController;
    private List<RegimenFiscal> regimenFiscal;
    private String id;
    private String name;
    private String gerente;
    private String businessName;
    private String rfc;
    private String mail;
    private String taxRegime;
    private String address;
    private String suburb;
    private String state;
    private String municipality;
    private String postalCode;
    private String phone;
    private String certificatePassWord;
    private UploadedFile certificate;
    private UploadedFile certificateKey;
    private InputStream certificateInputStream;
    private InputStream keyInputStream;
    private boolean peronsaFisica;
    private String printerName;
    private List<String> printerList;
    private Integer maxPerson;
    private UploadedFile file;

    private DocumentoController controladorDocumento;

    private LocationController controller;

    private UserController userController;
    private UserLocationController userLocationController;
    private List<User> listUser;
    private String selectedUse;
    private List<UserLocation> listUserLocation;
    private UserLocation selectedUserLocation;
    private List<LocationPaquetes> listLocationPaquetes;
    private List<Paquetes> listPaquetes;
    private String idPaquete;
    private LocationPaquetes selectLocationPaquetes;
    private Boolean packDemo;
    private String selectIdPaquete;
    private Location locationLogo;
}
