package gui;

import exceptions.DatabaseIOException;
import exceptions.InvalidUserException;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class LoginPanel extends JPanel implements ActionListener {

    private final FigrFrame figrFrame; // Parent frame.
    private final LogoPanel logo; // Figr logo.
    private final JTextField userName; // User name text field.
    private final JPasswordField password; // Password field.


    /**
     * Sets up LoginPanel with a new LogoPanel.
     */
    public LoginPanel(FigrFrame figrFrame) {
        this(figrFrame, new LogoPanel());
    }


    /**
     * Sets up LoginPanel with the passed LogoPanel.
     */
    public LoginPanel(FigrFrame figrFrame, LogoPanel logoPanel) {
        this.figrFrame = figrFrame;
        logo = logoPanel;

        // Set properties of LoginPanel.
        setLayout(new GridBagLayout());
        setBackground(FigrFrame.BACKGROUND_COLOR);


        /*
         Add components to this LoginPanel.
        */

        int paddingPixels = 25;

        // Add logo to this LoginPanel.
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.insets = new Insets(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
        gbc.anchor = GridBagConstraints.CENTER;
        add(logo, gbc);

        // Create existingUser panel and add to this LoginPanel.
        JPanel existingUser = new JPanel();
        gbc.gridy = 1;
        gbc.insets = new Insets(0, paddingPixels, paddingPixels, paddingPixels);
        add(existingUser, gbc);

        // Create newUser panel and add to this LoginPanel.
        JPanel newUser = new JPanel();
        gbc.gridy = 2;
        add(newUser, gbc);


        /*
         Set properties of 'existingUser' panel and add necessary components.
        */

        // Properties.
        existingUser.setLayout(new GridBagLayout());
        existingUser.setBorder(BorderFactory.createLineBorder(FigrFrame.BORDER_COLOR));
        existingUser.setBackground(FigrFrame.FOREGROUND_COLOR);

        // User name JLabel component.
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(paddingPixels, paddingPixels, 0, paddingPixels);
        gbc.gridy = 0;
        JLabel label = new JLabel("User Name");
        label.setPreferredSize(new Dimension(225, label.getPreferredSize().height));
        existingUser.add(label, gbc);

        // Password JLabel component.
        gbc.gridy = 2;
        gbc.insets = new Insets(15, paddingPixels, 0, paddingPixels);
        label = new JLabel("Password");
        existingUser.add(label, gbc);


        // Username JTextField component.
        gbc.insets = new Insets(0, paddingPixels, 0, paddingPixels);
        gbc.gridy = 1;
        userName = new JTextField();
        userName.setActionCommand("login");
        userName.addActionListener(this);
        userName.setPreferredSize(new Dimension(userName.getPreferredSize().width, 25));
        userName.setBorder(BorderFactory.createLineBorder(FigrFrame.FOREGROUND_COLOR.darker()));
        existingUser.add(userName, gbc);


        // Password JPasswordField component.
        gbc.gridy = 3;
        password = new JPasswordField();
        password.setActionCommand("login");
        password.addActionListener(this);
        password.setPreferredSize(userName.getPreferredSize());
        password.setBorder(userName.getBorder());
        existingUser.add(password, gbc);


        // Login JButton component.
        gbc.fill = GridBagConstraints.NONE;
        gbc.insets = new Insets(paddingPixels, 0, paddingPixels, 0);
        gbc.gridy = 4;
        JButton loginButton = new JButton("Login");
        loginButton.setPreferredSize(new Dimension(125, loginButton.getPreferredSize().height));
        loginButton.setActionCommand("login");
        loginButton.addActionListener(this);
        existingUser.add(loginButton, gbc);


        /*
         Set properties of 'newUser' panel and add necessary components.
        */

        // Properties.
        newUser.setLayout(new GridBagLayout());
        newUser.setBorder(BorderFactory.createLineBorder(FigrFrame.BORDER_COLOR));
        newUser.setBackground(FigrFrame.FOREGROUND_COLOR);

        // Create account component.
        gbc.gridy = 0;
        gbc.insets = new Insets(paddingPixels, 0, paddingPixels, 0);
        JButton createButton = new JButton("Create Account");
        createButton.setPreferredSize(loginButton.getPreferredSize());
        createButton.setActionCommand("create");
        createButton.addActionListener(this);
        newUser.add(createButton, gbc);
        newUser.setPreferredSize(new Dimension(existingUser.getPreferredSize().width, newUser.getPreferredSize().height));

        // Hide menu bar
        figrFrame.getJMenuBar().setVisible(false);
    }


    /**
     * Handles clicks on login button and create account button.
     */
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("login")) {
            // Login...
            try {
                figrFrame.login(userName.getText(), password.getPassword());

                // On successful login change FigrFrames panel to MainMenuPanel.
                figrFrame.changeInternalPanel(new MainMenuPanel(figrFrame));

            } catch (InvalidUserException e1) {
                // Login failed - display error message to alert user.
                JOptionPane.showMessageDialog(this, e1.getMessage() + ".\nPlease try again.", "Login failed", JOptionPane.ERROR_MESSAGE);
            } catch (DatabaseIOException e1) {
                // Database read failure - display unexpected error message.
                JOptionPane.showMessageDialog(this, "An unexpected error occurred while attempting to login user. Please try again later.\nIf this error persists contact your system administrator.", "Unexpected error", JOptionPane.ERROR_MESSAGE);
            }
        } else if (e.getActionCommand().equals("create")) {
            // Create Account...
            // Change FigrFrames panel to CreateUserPanel.
            figrFrame.changeInternalPanel(new CreateUserPanel(figrFrame, true, logo));
        }
    }

}


