package sac.gui.handler;

import java.io.IOException;
import java.util.Map;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;

import sac.fachada.SACFachada;
import sac.droga.Droga;
import sac.droga.DrogaNaoCadastradaException;
import sac.droga.DrogaJaCadastradaException;
import sac.exception.ItemJaCadastradoException;
import sac.exception.NullArgumentException;
import sac.exception.InvalidArgumentException;
import sac.exception.ItemNaoCadastradoException;
import sac.persistencia.PersistenceException;
import sac.gui.bean.DrogaBean;
import sac.gui.bean.CampoInvalidoException;
import sac.persistencia.OID;
import sac.pessoa.UsuarioComum;

/**
 * Handler para o formulário de login no sistema.
 *
 */
public class DrogaHandler extends SACHandler {
        /** Constantes utilizadas no Request desse Handler.*/
    public static final String DROGA_BEAN_REQUEST = "drogaBean";
    public static final String DROGA_BEAN_LIST_REQUEST = "drogas";
    public static final String DROGA_ERRO = "drogaErro";

    public static final String URL_OPERACAO_OK = "/jsp/operacaoOk.jsp";
    public static final String URL_CADASTRO_DROGA = "/jsp/cadastroDroga.jsp";
    public static final String URL_CONSULTA_DROGAS = "/jsp/consultaDrogas.jsp";
    public static final String URL_EXIBIR_DROGA = "/jsp/exibirDroga.jsp";
    public static final String URL_EXIBIR_DROGAS = "/jsp/exibirDrogas.jsp";

    private static final String OPERACAO_INICIALIZAR_FORMULARIO_DROGA = "InicializarFormularioDrogaOperation";
    private static final String OPERACAO_CADASTRAR_DROGA = "CadastrarDrogaOperation";
    private static final String OPERACAO_CONSULTA_DROGAS = "InicializarFormularioConsultaOperation";
    private static final String OPERACAO_CONSULTAR_DROGA_PARAMETRIZADA = "ConsultarDrogaParametrizadaOperation";
    private static final String OPERACAO_CONSULTAR_DROGA = "ConsultarDrogaOperation";
    private static final String OPERACAO_ALTERAR_DROGA = "AlterarDrogaOperation";

    /** Guarda o mapeamento (operacao, Handler)   */
    protected Map functionImplementers;

    /** Guarda o último handler solicitado. */
    protected SACHandler currentImplementer;

    /** Guarda a última operação solicitada. */
    protected String currentFunction;

    /** Creates new MenuHandler */
    public DrogaHandler() {
        super();
        this.functionImplementers = new Hashtable();
        this.functionImplementers.put(OPERACAO_INICIALIZAR_FORMULARIO_DROGA, new InicializarFormularioDrogaHandler());
        this.functionImplementers.put(OPERACAO_CADASTRAR_DROGA, new CadastrarDrogaHandler());
        this.functionImplementers.put(OPERACAO_CONSULTA_DROGAS, new InicializarFormularioConsultaHandler());
        this.functionImplementers.put(OPERACAO_CONSULTAR_DROGA, new ConsultarDrogaHandler());
        this.functionImplementers.put(OPERACAO_CONSULTAR_DROGA_PARAMETRIZADA, new ConsultarDrogaParametrizadaHandler());
        this.functionImplementers.put(OPERACAO_ALTERAR_DROGA, new AlterarDrogaHandler());
    }

    /** Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @param fachada fachada do Sistema
     * @return String a url do form a ser retornado
     */
    public String processRequest(HttpServletRequest request, HttpServletResponse response, SACFachada sacFachada)
    throws ServletException, IOException {
        String functionName = request.getParameter(SACHandler.FUNCTION_ID);
        String res = null;
        Object handler;
        if (functionName.equals(currentFunction)) {
            handler = currentImplementer;
        } else {
            handler = functionImplementers.get(functionName);
        }
        if (handler != null) {
            res = ((SACHandler) handler).processRequest(request, response, sacFachada);
            this.currentFunction = functionName;
            this.currentImplementer = (SACHandler) handler;
        } else {
            System.out.println("Nao conseguiu obter o handler " + functionName);
        }
        return res;
    }

    /**
     * Handler para a operacao de cadastro de Droga no sistema.
     */
    private class CadastrarDrogaHandler extends SACHandler {
        /** Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
         * @param request servlet request
         * @param response servlet response
         * @param fachada fachada do Sistema
         * @return String a url do form a ser retornado
         */
         public String processRequest(HttpServletRequest request, HttpServletResponse response,
                 SACFachada fachada) throws ServletException, IOException {

            String res = null;
            Droga droga = null;
            DrogaBean drogaBean = null;

            try {
                OID oid = (OID) request.getSession().getAttribute(this.OID_SESSION);
                UsuarioComum operador = fachada.procuraUsuario(oid, UsuarioComum.STATUS_OPERADOR);
                if(operador != null) {
                    drogaBean = new DrogaBean(request);
                    drogaBean.validaBean();
                    droga = drogaBean.getDroga();
                    fachada.cadastrarDroga(droga);
                    res = URL_OPERACAO_OK;
                }
            } catch(CampoInvalidoException exc) {
                request.setAttribute(DROGA_BEAN_REQUEST, drogaBean);
                res = URL_CADASTRO_DROGA;
            } catch (ItemJaCadastradoException exc) {
                drogaBean.setMensagemErro("Droga já cadastrada, Por favor, verifique os dados da droga");
                request.setAttribute(DROGA_BEAN_REQUEST, drogaBean);
                res = URL_CADASTRO_DROGA;
            } catch (ItemNaoCadastradoException exc) {
                drogaBean.setMensagemErro("O usuario não possui permissão para cadastrar a Droga");
                request.setAttribute(DROGA_BEAN_REQUEST, drogaBean);
                res = URL_CADASTRO_DROGA;
            } catch (InvalidArgumentException exc) {
                drogaBean.setMensagemErro(exc.getMessage());
                request.setAttribute(DROGA_BEAN_REQUEST, drogaBean);
                res = URL_CADASTRO_DROGA;
            } catch(NullArgumentException exc) {
                throw new ServletException(exc);
            } catch (PersistenceException exc) {
                throw new ServletException(exc);
            }
            return res;
        }
    }

    private class AlterarDrogaHandler extends SACHandler {
        public String processRequest(HttpServletRequest request, HttpServletResponse response,
                 SACFachada fachada) throws ServletException, IOException {

            String res = null;
            Droga droga = null;
            Droga newDroga = null;
            DrogaBean drogaBean = null;

            try {
                OID oid = (OID) request.getSession().getAttribute(this.OID_SESSION);
                UsuarioComum operador = fachada.procuraUsuario(oid, UsuarioComum.STATUS_OPERADOR);
                if(operador != null) {
                    drogaBean = new DrogaBean(request);
                    droga = fachada.procurarDroga(new OID(Long.parseLong(request.getParameter("oid"))));
                    drogaBean.validaBean();
                    newDroga = drogaBean.getDroga();
                    fachada.alterarDroga(droga, newDroga);
                    res = URL_OPERACAO_OK;
                }
            } catch(CampoInvalidoException exc) {
                request.setAttribute(DROGA_BEAN_REQUEST, drogaBean);
                res = URL_EXIBIR_DROGA;
            } catch(NullArgumentException exc) {
                drogaBean.setMensagemErro(exc.getMessage());
                request.setAttribute(DROGA_BEAN_REQUEST, drogaBean);
                res = URL_EXIBIR_DROGA;
            }catch (ItemNaoCadastradoException exc) {
                throw new ServletException(exc);
            }catch (InvalidArgumentException exc) {
                throw new ServletException(exc);
            } catch (PersistenceException exc) {
                throw new ServletException(exc);
            }
            return res;
        }
    }

    private class ConsultarDrogaHandler extends SACHandler {
        public String processRequest(HttpServletRequest request, HttpServletResponse response,
                 SACFachada fachada) throws ServletException, IOException {

            String res = null;
            try {
                String oid = request.getParameter(DrogaBean.INPUT_OID);
                DrogaBean drogaBean = new DrogaBean(fachada.procurarDroga(new OID(Long.parseLong(oid))));
                request.setAttribute(DROGA_BEAN_REQUEST, drogaBean);
                res = URL_EXIBIR_DROGA;
            }catch (ItemNaoCadastradoException exc) {
                throw new ServletException(exc);
            } catch(NullArgumentException exc) {
                throw new ServletException(exc);
            }catch (InvalidArgumentException exc) {
                throw new ServletException(exc);
            } catch (PersistenceException exc) {
                throw new ServletException(exc);
            }
            return res;
        }
    }

    private class ConsultarDrogaParametrizadaHandler extends SACHandler {
        private static final String INPUT_TIPO_CONSULTA = "tipoConsulta";
        private static final String INPUT_CONSULTA = "consulta";

        public String processRequest(HttpServletRequest request, HttpServletResponse response,
                 SACFachada fachada) throws ServletException, IOException {

            String res = null;
            try {
                String tipo = request.getParameter(INPUT_TIPO_CONSULTA);
                String consulta = request.getParameter(INPUT_CONSULTA);

                if(tipo.equals(DrogaBean.INPUT_ACOES_TERAPEUTICAS)) {
                    Iterator iterator = fachada.procurarDrogaPorAcoesTerapeuticas(consulta).iterator();
                    List drogas = new LinkedList();
                    while(iterator.hasNext()) {
                        Droga droga = (Droga) iterator.next();
                        DrogaBean drogaBean = new DrogaBean(droga);
                        drogas.add(drogaBean);
                    }
                    request.setAttribute(DROGA_BEAN_LIST_REQUEST, drogas);
                    res = URL_EXIBIR_DROGAS;
                } else if(tipo.equals(DrogaBean.INPUT_NOME)) {
                    Iterator iterator = fachada.procurarDrogaPeloNome(consulta).iterator();
                    List drogas = new LinkedList();
                    while(iterator.hasNext()) {
                        Droga droga = (Droga) iterator.next();
                        DrogaBean drogaBean = new DrogaBean(droga);
                        drogas.add(drogaBean);
                    }
                    request.setAttribute(DROGA_BEAN_LIST_REQUEST, drogas);
                    res = URL_EXIBIR_DROGAS;
                }
            }catch (ItemNaoCadastradoException exc) {
                throw new ServletException(exc);
            } catch(NullArgumentException exc) {
                throw new ServletException(exc);
            } catch (PersistenceException exc) {
                throw new ServletException(exc);
            }
            return res;
        }
    }

    private class InicializarFormularioDrogaHandler extends SACHandler {
          public String processRequest(HttpServletRequest request, HttpServletResponse response,
                 SACFachada fachada) throws ServletException, IOException {

            DrogaBean drogaBean = new DrogaBean();
            request.setAttribute(DROGA_BEAN_REQUEST, drogaBean);
            return URL_CADASTRO_DROGA;
         }
    }

   private class InicializarFormularioConsultaHandler extends SACHandler {
        public String processRequest(HttpServletRequest request, HttpServletResponse response,
                 SACFachada fachada) throws ServletException, IOException {

            DrogaBean drogaBean = new DrogaBean();
            request.setAttribute(DROGA_BEAN_REQUEST, drogaBean);
            return URL_CONSULTA_DROGAS;
         }
    }

}