package sac.gui.handler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;


import sac.exception.InvalidArgumentException;
import sac.fachada.SACFachada;
import sac.gui.bean.EnderecoBean;
import sac.gui.bean.PreOperationPJBean;
import sac.gui.bean.PessoaJuridicaBean;
import sac.persistencia.PersistenceException;
import sac.pessoa.endereco.Endereco;
import sac.pessoa.juridica.FiltroBuscaPessoaJuridica;
import sac.pessoa.juridica.PessoaJuridica;

public class ConsultaPJHandler extends SACHandler {

    /** 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;

    private final String CONSULTA_OPERATION = "CONSULTA_OPERATION";
    private final String PRE_OPERATION = "PRE_OPERATION";


    private final String URL_CONSULTA_PJ = "/jsp/consultaPJ.jsp";
    private final String PRE_OPERATION_PJ_BEAN_REQUEST = "preOperationPJ";
    private static final String RESPOSTA_PJ_BEAN_REQUEST = "resposta_consultaPJ";
    private static final String MESSAGE_ERRO_REQUEST = "mensagem_erro";


    private static final String START_INPUT = "start";
    private static final String SIZE_INPUT = "size";
    private static final String NOME_INPUT = "nome";
    private static final String CATEGORIA_INPUT = "categoria";
    private static final String SUB_CATEGORIA_INPUT = "subcategoria";
    private static final String CIDADE_INPUT = "cidade";
    private static final String ESTADO_INPUT = "estado";
    private static final String PAIS_INPUT = "pais";

    private static final String TYPE_INPUT = "tipo_consulta";

    public ConsultaPJHandler() {
        super();
        this.functionImplementers = new Hashtable();
        init();
    }

    private void init() {
        // preenchendo a funcao de operacoes do Handler
        functionImplementers.put(CONSULTA_OPERATION, new ConsultaHandler());
        functionImplementers.put(PRE_OPERATION, new PreencherFormHandler());
    }


    /** 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 functionName = request.getParameter(SACHandler.FUNCTION_ID);
        String result = null;
        SACHandler handler;

        if (functionName.equals(currentFunction)) {
            handler = currentImplementer;
        } else {
            handler = (SACHandler) functionImplementers.get(functionName);
            this.currentFunction = functionName;
            this.currentImplementer = handler;
        }
        if (handler != null) {
            result = handler.processRequest(request, response, fachada);
        } else {
            System.out.println("Nao conseguiu obter o handler " + functionName);
        }
        return result;
    }

    public String preencherFormPadrao(HttpServletRequest request,
        SACFachada fachada) throws ServletException {
        PreOperationPJBean prePJ;
        try {
            prePJ = createPreOperationBean(fachada);
        } catch ( PersistenceException pe){
            throw new ServletException ("Nao foi possivel criar Bean, "+ pe.getMessage() );
        }
        request.setAttribute(START_INPUT, new Integer(0) );
        request.setAttribute(SIZE_INPUT, new Integer(10) );
        request.setAttribute( NOME_INPUT, "");
        request.setAttribute( CATEGORIA_INPUT, "");
        request.setAttribute( SUB_CATEGORIA_INPUT, "");
        request.setAttribute( CIDADE_INPUT, "");
        request.setAttribute( ESTADO_INPUT, "");
        request.setAttribute( PAIS_INPUT, "");
        request.setAttribute( TYPE_INPUT, "e");

        request.setAttribute(PRE_OPERATION_PJ_BEAN_REQUEST, prePJ);
        return URL_CONSULTA_PJ;
    }

    private PreOperationPJBean createPreOperationBean ( SACFachada fachada)
        throws PersistenceException {
        Map mapcategorias = fachada.listarCategorias();

        return  new PreOperationPJBean( mapcategorias);
    }

    private PessoaJuridicaBean createPessoaJuridicaBean( PessoaJuridica pessoa) {
        List enderecos = pessoa.getEnderecos();
        List enderecosbean = new ArrayList();
        for (int i = 0; i < enderecos.size(); i++) {
            Endereco endereco = (Endereco) enderecos.get(i);
            enderecosbean.add( new EnderecoBean (endereco.getRua(),
              endereco.getBairro(), endereco.getCidade(),
              endereco.getEstado(), endereco.getPais(), endereco.getCep(),
              endereco.getTelefone(), endereco.getEmail()) );
        }

        return  new PessoaJuridicaBean (pessoa.getNome(), pessoa.getCnpj(),
            enderecosbean, pessoa.getHomePage(), pessoa.getInscricaoEstadual(),
            pessoa.getInscricaoMunicipal(), pessoa.getServicosOferecidos(),
            pessoa.getCategorias());

    }

    /**
     * Handler para a operacao de consulta de Pessoa física no sistema.
     */
    private class ConsultaHandler 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 {

            try {
                request.setAttribute( NOME_INPUT, request.getParameter(NOME_INPUT));
                request.setAttribute( CATEGORIA_INPUT, request.getParameter(CATEGORIA_INPUT));
                request.setAttribute( SUB_CATEGORIA_INPUT, request.getParameter(SUB_CATEGORIA_INPUT));
                request.setAttribute( CIDADE_INPUT, request.getParameter(CIDADE_INPUT));
                request.setAttribute( ESTADO_INPUT, request.getParameter(ESTADO_INPUT));
                request.setAttribute( PAIS_INPUT, request.getParameter(PAIS_INPUT));
                request.setAttribute( TYPE_INPUT, request.getParameter(TYPE_INPUT));



                request.setAttribute(PRE_OPERATION_PJ_BEAN_REQUEST, createPreOperationBean(fachada));

                String nome = request.getParameter(NOME_INPUT);
                String categoria = request.getParameter(CATEGORIA_INPUT);
                String sub_categoria = request.getParameter(SUB_CATEGORIA_INPUT);
                String cidade = request.getParameter(CIDADE_INPUT);
                String estado = request.getParameter(ESTADO_INPUT);
                String pais = request.getParameter(PAIS_INPUT);
                String tipo_consulta = request.getParameter(TYPE_INPUT);


                String sizeStr = request.getParameter(SIZE_INPUT);
                String startIndexStr = request.getParameter(START_INPUT);


                FiltroBuscaPessoaJuridica filtro = new FiltroBuscaPessoaJuridica();

                if ( "e".equals(tipo_consulta) ){
                    filtro.setConectivo( filtro.AND);
                } else if ("ou".equals(tipo_consulta) ) {
                    filtro.setConectivo( filtro.OR);
                } else {
                    throw new ServletException ("conectivo invalido, conctivo="+
                        tipo_consulta);
                }

                if ( !"".equals( nome)){
                    filtro.setNome(nome);
                }
                if ( !"".equals( categoria)){
                    filtro.setCategoria(categoria);
                }
                if ( !"".equals( sub_categoria)){
                    filtro.setSubcategoria(sub_categoria);
                }
                if ( !"".equals( cidade)){
                    filtro.setNome(cidade);
                }

                if ( !"".equals( estado)){
                    filtro.setEstado(estado);
                }
                if ( !"".equals( pais)){
                    filtro.setPais(pais);
                }

                int size, start;
                size = Integer.valueOf(sizeStr).intValue();
                start = Integer.valueOf(startIndexStr).intValue();

                List listaPessoas = fachada.consultaPessoaJuridica( filtro, start, size +1);


                List pessoasbean = new ArrayList();
                boolean has_next = listaPessoas.size() > size;
                int tamanho_apresentacao = (has_next)? listaPessoas.size()-1 : listaPessoas.size();
                for (int i = 0; i < tamanho_apresentacao ; i++) {
                    PessoaJuridica pessoa = (PessoaJuridica) listaPessoas.get(i);
                    pessoasbean.add( createPessoaJuridicaBean( pessoa));
                }


                request.setAttribute("start", new Integer(start) );
                request.setAttribute("size", new Integer(size) );
                request.setAttribute("has_next", new Boolean(has_next));

                request.setAttribute(RESPOSTA_PJ_BEAN_REQUEST, pessoasbean);

                return URL_CONSULTA_PJ;
            } catch (PersistenceException pe ){
                pe.printStackTrace();
                throw new ServletException("Nao foi possivel realizar a consulta",
                    pe);
            } catch (InvalidArgumentException iae){
                throw new ServletException("Erro Interno,"+ iae.getMessage());
            }
        }

    }

    /**
     * Handler para a operacao de preencher campos defalut na consultar por Pessoa física.
     */
    private class PreencherFormHandler 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 {

            return preencherFormPadrao(request, fachada);
        }
    }
}