/*
 * 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 br.com.ctecinf;

import br.com.ctecinf.swing.Image;
import br.com.ctecinf.swing.OptionPane;
import br.com.ctecinf.swing.PleaseWaitDialog;
import br.com.ctecinf.text.MaskFormatter;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.SwingUtilities;

/**
 *
 * @author Cássio Conceição
 * @since 19/09/2018
 * @version 201809
 * @see http://ctecinf.com.br
 */
public abstract class Login extends JFrame implements ActionListener {

    private static final String SERVER_URL = "jdbc:mysql://ctecinf.com.br/ctecinfc_sistema";
    private static final String SERVER_USER = "ctecinfc_root";
    private static final String SERVER_PASS = "S0&zYBQqLX)k";

    private JFormattedTextField user;
    private JPasswordField pass;
    private JComboBox tpAmb;

    public Login() {
        init();
    }

    private void init() {

        setLayout(new BorderLayout(30, 30));
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        JPanel panel = new JPanel(new BorderLayout()) {

            @Override
            protected void paintComponent(Graphics g) {

                super.paintComponent(g);

                StringBuilder sb = new StringBuilder();
                sb.append(Image.BACKGROUND_PART1);
                sb.append(Image.BACKGROUND_PART2);
                sb.append(Image.BACKGROUND_PART3);
                sb.append(Image.BACKGROUND_PART4);
                sb.append(Image.BACKGROUND_PART5);
                sb.append(Image.BACKGROUND_PART6);
                sb.append(Image.BACKGROUND_PART7);

                g.drawImage(Image.parse(sb.toString()).getImage(), 0, 0, null);

                java.awt.Image img = Image.parse(Image.LOGO, 250).getImage();

                BufferedImage buff = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);

                Graphics2D g2d = (Graphics2D) buff.getGraphics();

                AlphaComposite alphaChannel = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.35f);
                g2d.setComposite(alphaChannel);
                g2d.drawImage(img, 0, 0, null);

                g.drawImage(buff, super.getWidth() - 255, super.getHeight() - 110, null);
            }
        };

        add(panel);

        JPanel mainPanel = new JPanel(new GridBagLayout());
        mainPanel.setOpaque(false);

        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        buttonPanel.setOpaque(false);

        String[] values = {"Produção", "Homologação"};

        tpAmb = new JComboBox(values);

        if (Config.get("nfe.amb").equals("1")) {
            tpAmb.setSelectedItem("Produção");
        } else {
            tpAmb.setSelectedItem("Homologação");
        }

        user = new JFormattedTextField(new MaskFormatter("##.###.###/####-##"));
        user.setValue(Config.get("user.cnpj"));
        user.setColumns(15);
        user.setFont(user.getFont().deriveFont(20f));
        user.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    login();
                }
            }
        });

        pass = new JPasswordField();
        pass.setColumns(15);
        pass.setFont(pass.getFont().deriveFont(20f));
        pass.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    login();
                }
            }
        });

        JLabel slogan = new JLabel("Sistemas Gerenciais - ctecinf.com.br (Login Sistema NFC-e)", JLabel.CENTER);
        slogan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        slogan.setFont(slogan.getFont().deriveFont(12f));
        slogan.setForeground(Color.WHITE);

        JLabel lAmb = new JLabel("NFC-e ", JLabel.RIGHT);
        lAmb.setFont(lAmb.getFont().deriveFont(20f));
        lAmb.setForeground(Color.WHITE);

        JLabel lUser = new JLabel("CNPJ ", JLabel.RIGHT);
        lUser.setFont(lUser.getFont().deriveFont(20f));
        lUser.setForeground(Color.WHITE);

        JLabel lPass = new JLabel("Senha ", JLabel.RIGHT);
        lPass.setFont(lPass.getFont().deriveFont(20f));
        lPass.setForeground(Color.WHITE);

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.BOTH;

        gbc.gridy = 1;
        gbc.gridx = 1;
        mainPanel.add(lAmb, gbc);

        gbc.gridx = 2;
        mainPanel.add(tpAmb, gbc);

        JPanel p = new JPanel();
        p.setOpaque(false);

        gbc.gridy = 2;
        gbc.gridx = 1;
        mainPanel.add(p, gbc);

        p = new JPanel();
        p.setOpaque(false);

        gbc.gridx = 2;
        mainPanel.add(p, gbc);

        gbc.gridy = 3;
        gbc.gridx = 1;
        mainPanel.add(lUser, gbc);

        gbc.gridx = 2;
        mainPanel.add(user, gbc);

        p = new JPanel();
        p.setOpaque(false);

        gbc.gridy = 4;
        gbc.gridx = 1;
        mainPanel.add(p, gbc);

        p = new JPanel();
        p.setOpaque(false);

        gbc.gridx = 2;
        mainPanel.add(p, gbc);

        gbc.gridy = 5;
        gbc.gridx = 1;
        mainPanel.add(lPass, gbc);

        gbc.gridx = 2;
        mainPanel.add(pass, gbc);

        JButton button = new JButton("Acessar", Image.parse(Image.SUCCESS));
        button.addActionListener(this);
        buttonPanel.add(button);

        button = new JButton("Sair", Image.parse(Image.EXIT));
        button.addActionListener(this);
        buttonPanel.add(button);

        p = new JPanel();
        p.setOpaque(false);

        gbc.gridy = 6;
        gbc.gridx = 1;
        mainPanel.add(p, gbc);

        gbc.gridx = 2;
        mainPanel.add(buttonPanel, gbc);

        JLabel nfce = new JLabel(Image.parse(Image.NFCE), JLabel.LEFT);
        nfce.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        JPanel pNFCe = new JPanel(new BorderLayout());
        pNFCe.setOpaque(false);
        pNFCe.add(nfce, BorderLayout.SOUTH);

        panel.add(slogan, BorderLayout.NORTH);
        panel.add(mainPanel, BorderLayout.CENTER);
        panel.add(pNFCe, BorderLayout.SOUTH);

        setAlwaysOnTop(true);
        setUndecorated(true);
        setSize(600, 400);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    @Override
    public void setVisible(boolean b) {

        super.setVisible(b);

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {

                File file = new File(Config.FILE_NAME);

                if (file.exists()) {
                    pass.requestFocus();
                } else {

                    try (OutputStream output = new FileOutputStream(file)) {

                        Properties prop = new Properties();

                        prop.setProperty("db.jdbc", "firebird");
                        prop.setProperty("db.host", "localhost");
                        prop.setProperty("db.name", new File("data.fdb").getAbsolutePath());
                        prop.setProperty("db.user", "sysdba");
                        prop.setProperty("db.pass", "masterkey");
                        prop.setProperty("user.cnpj", "");
                        prop.setProperty("logo.path", "");
                        prop.setProperty("nfe.xml.path", "");
                        prop.setProperty("nfe.amb", "");

                        prop.store(output, null);

                        OptionPane.alert("Configure o arquivo de propriedades do sistema.");
                        Desktop.getDesktop().open(file);

                    } catch (IOException ex) {
                        System.err.println(ex);
                    }

                    user.requestFocus();
                }
            }
        });
    }

    public abstract void success();

    private void login() {

        new PleaseWaitDialog() {

            @Override
            public Object exec() {

                try {

                    String query = "SELECT r.*, t.mun_desc, t.uf_cod_ibge, t.uf_sigla "
                            + "FROM contribuinte r "
                            + "LEFT JOIN municipio t ON t.mun_cod_ibge = r.municipio_id "
                            + "WHERE cnpj = " + user.getValue();

                    Connection conn = DriverManager.getConnection(SERVER_URL, SERVER_USER, SERVER_PASS);

                    try (Statement st = conn.createStatement(); ResultSet rs = st.executeQuery(query)) {

                        if (rs.next()) {

                            Date now = Utils.dateFromServer().getTime();
                            Date licensa = rs.getDate("licensa");

                            if (rs.getString("senha").equalsIgnoreCase(Utils.md5(new String(pass.getPassword()))) && now.before(licensa)) {

                                Empresa.setBairro(rs.getString("bairro"));
                                Empresa.setCep(rs.getString("cep"));
                                Empresa.setCnpj(rs.getString("cnpj"));
                                Empresa.setComplemento(rs.getString("complemento"));
                                Empresa.setContadorCNPJ(rs.getString("contador_cnpj"));
                                Empresa.setFone(rs.getString("fone"));
                                Empresa.setFreteId(rs.getLong("frete_id"));
                                Empresa.setAliquota(rs.getDouble("aliquota"));
                                Empresa.setCfopId(rs.getLong("cfop_id"));
                                Empresa.setContadorEmail(rs.getString("contador_email"));
                                Empresa.setSerie(rs.getInt("serie"));
                                Empresa.setCscTokenHomo(rs.getString("csc_token_homo"));
                                Empresa.setCscTokenProd(rs.getString("csc_token_prod"));
                                Empresa.setIcmsId(rs.getLong("icms_id"));
                                Empresa.setIcmsOrigemId(rs.getLong("icms_origem_id"));
                                Empresa.setInscEstadual(rs.getString("insc_estadual"));
                                Empresa.setLogradouro(rs.getString("logradouro"));
                                Empresa.setMunicipio(rs.getString("mun_desc"));
                                Empresa.setMunicipioIBGE(rs.getLong("municipio_id"));
                                Empresa.setNatOperacao(rs.getString("nat_operacao"));
                                Empresa.setNomeFantasia(rs.getString("nome_fantasia"));
                                Empresa.setNumero(rs.getInt("numero"));
                                Empresa.setRazaoSocial(rs.getString("razao_social"));
                                Empresa.setSenhaCertificado(rs.getString("senha_certificado"));
                                Empresa.setSlogan(rs.getString("slogan"));
                                Empresa.setUf(rs.getString("uf_sigla"));
                                Empresa.setUfIBGE(rs.getInt("uf_cod_ibge"));
                                Empresa.setMensagem(rs.getString("message"));

                                if (tpAmb.getSelectedItem().toString().equalsIgnoreCase("Produção")) {
                                    System.setProperty("nfe_tp_amb", "1");
                                    Config.set("nfe.amb", "1");
                                } else {
                                    System.setProperty("nfe_tp_amb", "2");
                                    Config.set("nfe.amb", "2");
                                }

                                Timestamp ts = new Timestamp(now.getTime());

                                st.executeUpdate("UPDATE contribuinte SET last_access = '" + ts + "' WHERE cnpj = " + Empresa.getCnpj());

                                Config.set("user.cnpj", Empresa.getCnpj().trim());

                                Calendar cl = Calendar.getInstance();
                                cl.setTime(licensa);
                                cl.add(Calendar.DATE, -15);

                                if (now.after(cl.getTime())) {
                                    long diff = licensa.getTime() - now.getTime();
                                    JOptionPane.showMessageDialog(null, "Sua licensa vai expirar em " + TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS) + " dias!", "Alerta", JOptionPane.WARNING_MESSAGE, new ImageIcon());
                                }

                                Login.this.dispose();

                                return true;

                            } else if (now.after(licensa)) {

                                throw new Exception("Sua licensa expirou!\nEntre em contato com o suporte para regularizar seu cadastro.\nhttp://notafiscaleletronica-rs.com.br");

                            } else {

                                pass.requestFocus();
                                pass.selectAll();

                                throw new Exception("Senha inválida!");
                            }

                        } else {

                            user.requestFocus();
                            user.selectAll();

                            throw new Exception("Usuário não cadastrado!\nSolicite seu cadastro em http://ctecinf.com.br");
                        }
                    } finally {
                        conn.close();
                    }

                } catch (Exception ex) {

                    Object msg;

                    if (ex.getLocalizedMessage() == null) {
                        msg = "Preencher o campo senha!";
                        pass.requestFocus();
                    } else {
                        msg = ex.getLocalizedMessage();
                    }

                    System.err.println(msg);
                    JOptionPane.showMessageDialog(null, msg, "Erro", JOptionPane.ERROR_MESSAGE, new ImageIcon());
                }

                return false;
            }

            @Override
            public void end(Object result) {
                if ((Boolean) result) {
                    success();
                }
            }

        }.start();
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        if (e.getActionCommand().equalsIgnoreCase("acessar")) {
            login();
        } else {
            dispose();
        }
    }
}
