package sac.gui.handler;

import javax.servlet.*;
import javax.servlet.http.*;

import java.util.Vector;
import java.util.Hashtable;
import java.util.Map;
import java.io.IOException;

import sac.fachada.SACFachada;
import sac.pessoa.juridica.PessoaJuridica;
import sac.pessoa.juridica.CNPJInvalidoException;
import sac.exception.ItemJaCadastradoException;
import sac.pessoa.endereco.Endereco;
import sac.gui.bean.CadastroPJBean;
import sac.persistencia.PersistenceException;
import sac.exception.InvalidArgumentException;
import sac.exception.NullArgumentException;
import sac.pessoa.SenhaInvalidaException;

// ADD
import sac.persistencia.OID;
import sac.pessoa.UsuarioComum;
import sac.exception.ItemNaoCadastradoException;
/**
 * Handler para o formulário de cadastro de Pessoa Jurídica no sistema.
 *
 * @author  fcan, esrb
 */
public class MenuCadastroPJHandler extends SACHandler {

    /** Constante que define o Name do Hidden de um Form que
     * identifica unicamente o Handler que tratará a operação
     * de logar.
     */
    // FIXME - deve estar num arquivo de propriedades
    private static final String OPERACAO_CADASTRO = "CadastroOperation";
    private static final String OPERACAO_ALTERACAO = "AlteracaoOperation";

    /** 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 MenuCadastroPJHandler() {
        super();
        this.functionImplementers = new Hashtable();
        this.functionImplementers.put(OPERACAO_CADASTRO, new CadastroPJHandler());
        this.functionImplementers.put(OPERACAO_ALTERACAO, new AlteracaoPJHandler());
    }

    /** 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 Pessoa física no sistema.
     */
    private class CadastroPJHandler extends SACHandler {

     /** Constantes que guardam os caminhos dos JSP.
      *  FIXME isso tem que estar num arquivo!!!!!!!!!!!!
      */
      private static final String URL_CADASTRO_PJ_OK = "cadastroOk.html";
      private static final String URL_ERRO_CADASTRO_PJ = "/jsp/cadastroPJ_erro.jsp";

      /**
      Constantes utilizadas no Request desse Handler.*/
      private static final String CADASTRO_PJ_BEAN_REQUEST = "cadastroPJ";

      /** Constantes que definem os nomes dos Inputs do Form.
      */
      private static final String NOME_INPUT = "nome";
      private static final String CNPJ_INPUT = "cnpj";
      private static final String SENHA_INPUT = "senha";
      private static final String ENDERECO1_INPUT = "endereco1";
      private static final String ENDERECO2_INPUT = "endereco2";
      private static final String BAIRRO1_INPUT = "bairro1";
      private static final String CIDADE1_INPUT = "cidade1";
      private static final String ESTADO1_INPUT = "estado1";
      private static final String PAIS1_INPUT = "pai1s";
      private static final String CEP1_INPUT = "cep1";
      private static final String BAIRRO2_INPUT = "bairro2";
      private static final String CIDADE2_INPUT = "cidade2";
      private static final String ESTADO2_INPUT = "estado2";
      private static final String PAIS2_INPUT = "pais2";
      private static final String CEP2_INPUT = "cep2";
      private static final String TELEFONE_INPUT = "telefone1";
      private static final String EMAIL_INPUT = "email";
      private static final String INSC_MUN_INPUT = "inscMun" ;
      private static final String INSC_EST_INPUT = "inscEst" ;
      private static final String HOMEPAGE_INPUT = "homePage";
      private static final String TIPO_SERVICO_INPUT = "servicos";
      private static final String CATEGORIA_INPUT = " categoria";

      /** 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;
        PessoaJuridica pessoa = null;

        String nome = request.getParameter(NOME_INPUT);
        String cnpj  = request.getParameter(CNPJ_INPUT);
        String senha = request.getParameter(SENHA_INPUT);

        String endereco1 = request.getParameter(ENDERECO1_INPUT);

        System.out.println("Nome : " + nome +" / endereco = "+ endereco1);
//      endereco1 = (endereco1 == null )? "" : endereco1;

        String bairro1 = request.getParameter(BAIRRO1_INPUT);
        String cidade1 = request.getParameter(CIDADE1_INPUT);
        String estado1 = request.getParameter(ESTADO1_INPUT);
        String pais1 = request.getParameter(PAIS1_INPUT);
        String cep1 = request.getParameter(CEP1_INPUT);

        String endereco2 = request.getParameter(ENDERECO2_INPUT);
        String bairro2 = request.getParameter(BAIRRO2_INPUT);
        String cidade2 = request.getParameter(CIDADE2_INPUT);
        String estado2 = request.getParameter(ESTADO2_INPUT);
        String pais2 = request.getParameter(PAIS2_INPUT);
        String cep2 = request.getParameter(CEP2_INPUT);

        String telefone = request.getParameter(TELEFONE_INPUT);
        String email = request.getParameter(EMAIL_INPUT);
        String servicos = request.getParameter(TIPO_SERVICO_INPUT);
        String inscMun = request.getParameter(INSC_MUN_INPUT);
        String inscEst = request.getParameter(INSC_EST_INPUT);
        String homePage = request.getParameter(HOMEPAGE_INPUT);
        String categoria = request.getParameter(CATEGORIA_INPUT);

        CadastroPJBean cadastroPJBean = new CadastroPJBean();
        cadastroPJBean.setNome(nome);
        cadastroPJBean.setEmail1(email);
        cadastroPJBean.setCnpj(cnpj);
        cadastroPJBean.setSenha(senha);
        cadastroPJBean.setEndereco1(endereco1);
        cadastroPJBean.setBairro1(bairro1);
        cadastroPJBean.setCidade1(cidade1);
        cadastroPJBean.setEstado1(estado1);
        cadastroPJBean.setPais1(pais1);
        cadastroPJBean.setCep1(cep1);
        cadastroPJBean.setEndereco2(endereco2);
        cadastroPJBean.setBairro2(bairro2);
        cadastroPJBean.setCidade2(cidade2);
        cadastroPJBean.setEstado2(estado2);
        cadastroPJBean.setPais2(pais2);
        cadastroPJBean.setCep2(cep2);
        cadastroPJBean.setTelefone1(telefone);
        cadastroPJBean.setInscMun(inscMun);
        cadastroPJBean.setInscEst(inscEst);
        cadastroPJBean.setCategoria(categoria);
        cadastroPJBean.setHomePage(homePage);

        try {
          /**
           * Caso algum campo obrigatorio seja deixado em branco
           *
           * FIXME!!!
           * Falta verificar quias os obrigatorios pelo doc de requisistos!
           */
          if(nome.equals("") || cnpj.equals("") || senha.equals("") || endereco1.equals("") ||
                        bairro1.equals("") || cidade1.equals("") || estado1.equals("") ||
			pais1.equals("") || cep1.equals("") || telefone.equals("") ||
			servicos.equals("") || inscMun.equals("") ||  categoria.equals("") ) {

                cadastroPJBean.setPreenchimento("Os campos com * são de preenchimento obrigatório!");
                /** Insere bean no request*/
                request.setAttribute(CADASTRO_PJ_BEAN_REQUEST, cadastroPJBean);

                /** Define a página de resposta */
                res = URL_ERRO_CADASTRO_PJ;

          } else {
	          // Validando CNPJ...

                  // Map de categoria: como ele vem do form?
                  // lista de Insc Estaduais? pq eh lista e municipal e unica?
                  Vector listaInscEst = new Vector();
                  listaInscEst.add(inscEst);
	          pessoa = new PessoaJuridica(nome, cnpj, senha, new Hashtable(),
                                              inscMun, listaInscEst);

                  pessoa.setCnpj(cnpj);
                  Vector enderecos = new Vector();
                  // Validar o preenchimento de enderecos
                  enderecos.add(endereco1);
                  enderecos.add(endereco2);
 		  pessoa.setEnderecos(enderecos);
	          pessoa.setHomePage(homePage);
		  //???????????????????
                  //pessoa.setOferta(/*???????*/);
		  //pessoa.setServicosOferecidos(/*???????*/);

	          //Fachada mais certa com Passaro, acrescenta esse método!!!!!!!!!!!!!!
	          fachada.cadastraPessoaJuridica(pessoa);

	          res = URL_CADASTRO_PJ_OK;
	  }

        /**
         * Caso o CNPJ seja invalido...
         */
        } catch (CNPJInvalidoException cnpje) {

            cadastroPJBean.setErroCnpjInvalido("CNPJ Inválido");

            /** Insere o Bean no request. */
            request.setAttribute(CADASTRO_PJ_BEAN_REQUEST, cadastroPJBean);

            res = URL_ERRO_CADASTRO_PJ;
        /**
         * Caso a senha seja invalida...
         */
        } catch (SenhaInvalidaException sie) {
            cadastroPJBean.setErroSenha("Senha inválida. Deve possuir mais de 4 caracteres.");

           /** Insere o Bean no request. */
            request.setAttribute(CADASTRO_PJ_BEAN_REQUEST, cadastroPJBean);

            res = URL_ERRO_CADASTRO_PJ;
        /**
         * Caso a pessoa ja esteja cadastrada...
         */
        } catch (ItemJaCadastradoException ijce) {

            cadastroPJBean.setErroPessoaJaCadastrada("CNPJ já cadastrado");

            /** Insere o Bean no request. */
            request.setAttribute(CADASTRO_PJ_BEAN_REQUEST, cadastroPJBean);

            res = URL_ERRO_CADASTRO_PJ;
        } catch (PersistenceException pe) {

            cadastroPJBean.setErroPersistencia("Problemas na conexão com o BD");
            res = URL_ERRO_CADASTRO_PJ;

        } catch (InvalidArgumentException iae) {
            // Nao vai acontecer
        } catch (NullArgumentException nae) {
            // Nao vai acontecer
            nae.printStackTrace();
        }

        return res;

      }

    }

    // ADD essa classe

    /**
     * Handler para a operacao de alteracao de Pessoa Juridica no Sistema
     */
    private class AlteracaoPJHandler extends SACHandler {

         /** Constantes que guardam os caminhos dos JSP.
      *  FIXME isso tem que estar num arquivo!!!!!!!!!!!!
      */
      private static final String URL_CADASTRO_PJ_OK = "cadastroOk.html";
      private static final String URL_ERRO_CADASTRO_PJ = "/jsp/cadastroPJ_erro.jsp";

      /**
      Constantes utilizadas no Request desse Handler.*/
      private static final String CADASTRO_PJ_BEAN_REQUEST = "cadastroPJ";

      /** Constantes que definem os nomes dos Inputs do Form.
      */
      private static final String NOME_INPUT = "nome";
      private static final String CNPJ_INPUT = "cnpj";
      private static final String SENHA_INPUT = "senha";
      private static final String ENDERECO1_INPUT = "endereco1";
      private static final String ENDERECO2_INPUT = "endereco2";
      private static final String BAIRRO1_INPUT = "bairro1";
      private static final String CIDADE1_INPUT = "cidade1";
      private static final String ESTADO1_INPUT = "estado1";
      private static final String PAIS1_INPUT = "pai1s";
      private static final String CEP1_INPUT = "cep1";
      private static final String BAIRRO2_INPUT = "bairro2";
      private static final String CIDADE2_INPUT = "cidade2";
      private static final String ESTADO2_INPUT = "estado2";
      private static final String PAIS2_INPUT = "pais2";
      private static final String CEP2_INPUT = "cep2";
      private static final String TELEFONE1_INPUT = "telefone1";
      private static final String TELEFONE2_INPUT = "telefone2";
      private static final String EMAIL_INPUT = "email";
      private static final String INSC_MUN_INPUT = "inscMun" ;
      private static final String INSC_EST_INPUT = "inscEst" ;
      private static final String HOMEPAGE_INPUT = "homePage";
      private static final String TIPO_SERVICO_INPUT = "servicos";
      private static final String CATEGORIA_INPUT = " categoria";

      /** 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;
        PessoaJuridica pessoa = null;
        PessoaJuridica pessoaAntiga = null;

        String nome = request.getParameter(NOME_INPUT);
        String cnpj  = request.getParameter(CNPJ_INPUT);
        String senha = request.getParameter(SENHA_INPUT);

        String rua1 = request.getParameter(ENDERECO1_INPUT);

        System.out.println("Nome : " + nome +" / endereco = "+ rua1);
//      rua1 = (rua1 == null )? "" : rua1;

        String bairro1 = request.getParameter(BAIRRO1_INPUT);
        String cidade1 = request.getParameter(CIDADE1_INPUT);
        String estado1 = request.getParameter(ESTADO1_INPUT);
        String pais1 = request.getParameter(PAIS1_INPUT);
        String cep1 = request.getParameter(CEP1_INPUT);

        String rua2 = request.getParameter(ENDERECO2_INPUT);
        String bairro2 = request.getParameter(BAIRRO2_INPUT);
        String cidade2 = request.getParameter(CIDADE2_INPUT);
        String estado2 = request.getParameter(ESTADO2_INPUT);
        String pais2 = request.getParameter(PAIS2_INPUT);
        String cep2 = request.getParameter(CEP2_INPUT);

        String telefone1 = request.getParameter(TELEFONE1_INPUT);
        String telefone2 = request.getParameter(TELEFONE2_INPUT);

        String email = request.getParameter(EMAIL_INPUT);
        String servicos = request.getParameter(TIPO_SERVICO_INPUT);
        String inscMun = request.getParameter(INSC_MUN_INPUT);
        String inscEst = request.getParameter(INSC_EST_INPUT);
        String homePage = request.getParameter(HOMEPAGE_INPUT);
        String categoria = request.getParameter(CATEGORIA_INPUT);

        CadastroPJBean cadastroPJBean = new CadastroPJBean();
        cadastroPJBean.setNome(nome);
        cadastroPJBean.setEmail1(email);
        cadastroPJBean.setCnpj(cnpj);
        cadastroPJBean.setSenha(senha);
        cadastroPJBean.setEndereco1(rua1);
        cadastroPJBean.setBairro1(bairro1);
        cadastroPJBean.setCidade1(cidade1);
        cadastroPJBean.setEstado1(estado1);
        cadastroPJBean.setPais1(pais1);
        cadastroPJBean.setCep1(cep1);
        cadastroPJBean.setEndereco2(rua2);
        cadastroPJBean.setBairro2(bairro2);
        cadastroPJBean.setCidade2(cidade2);
        cadastroPJBean.setEstado2(estado2);
        cadastroPJBean.setPais2(pais2);
        cadastroPJBean.setCep2(cep2);
        cadastroPJBean.setTelefone1(telefone1);
        cadastroPJBean.setTelefone2(telefone2);
        cadastroPJBean.setInscMun(inscMun);
        cadastroPJBean.setInscEst(inscEst);
        cadastroPJBean.setCategoria(categoria);
        cadastroPJBean.setHomePage(homePage);

        try {

            OID oid = (OID) request.getSession().getAttribute(this.OID_SESSION);
            pessoaAntiga = (PessoaJuridica) fachada.procuraUsuario(oid, UsuarioComum.STATUS_PESSOA_JURIDICA);

            /**
            * Caso algum campo obrigatorio seja deixado em branco
            */
            if(nome.equals("") || cnpj.equals("") || senha.equals("") || rua1.equals("") ||
                        bairro1.equals("") || cidade1.equals("") || estado1.equals("") ||
			pais1.equals("") || cep1.equals("") || telefone1.equals("") ||
			servicos.equals("") || inscMun.equals("") ||  categoria.equals("") ) {

             	cadastroPJBean.setPreenchimento("Os campos com * são de preenchimento obrigatório!");

           	/** Insere bean no request*/
           	request.setAttribute(CADASTRO_PJ_BEAN_REQUEST, cadastroPJBean);

            } else {
	          Endereco endereco1 = new Endereco(rua1, bairro1, cidade1, estado1, pais1,
	                                          cep1, telefone1);
                  // FIXME: como deve ser o tratamento do endereco 2 vazio
                  // (ou parcialmente preenchido)?
                  Endereco endereco2 = new Endereco(rua2, bairro2, cidade2, estado2, pais2,
	                                          cep2, telefone2);
                  Vector enderecos = new Vector();
                  enderecos.add(endereco1);
                  enderecos.add(endereco2);

                  endereco1.setEmail(email);

                  // FIXME: como fazer o map de categorias do form:
                  Hashtable categorias = new Hashtable();
                  pessoa = new PessoaJuridica(nome, cnpj, senha, categorias, inscMun, enderecos);

                  fachada.alteraPessoa(pessoaAntiga, pessoa);
                  res = URL_CADASTRO_PJ_OK;
            } /**
               * Caso a senha seja invalida...
               */
          } catch (SenhaInvalidaException sie) {
              cadastroPJBean.setErroSenha("Senha inválida. Deve possuir mais de 4 caracteres.");
              request.setAttribute(CADASTRO_PJ_BEAN_REQUEST, cadastroPJBean);
          } catch (ItemNaoCadastradoException ijce) {
              // Nao dave acontecer...
              cadastroPJBean.setErroCnpjInvalido("Pessoa com CNPJ não registrada no sistema!");
              request.setAttribute(CADASTRO_PJ_BEAN_REQUEST, cadastroPJBean);
          } catch (PersistenceException pe) {
              cadastroPJBean.setErroPersistencia("Problemas na conexão com o BD");
              request.setAttribute(CADASTRO_PJ_BEAN_REQUEST, cadastroPJBean);
          /*} catch ( sac.doenca.DoencaNaoCadastradaException dnce) {
              dnce.printStackTrace();*/
          } catch (InvalidArgumentException iae) {
              // nao vai acontecer
              iae.printStackTrace();
          } catch (NullArgumentException nae) {
              // nao vai acontecer
              nae.printStackTrace();
          }

          return res;
      }

    }

    // ADD essa classe

    /**
     * Handler para preencher todo o menu de cadastro a partir da pessoa juridica
     * que está logada. Precisa ser chamado antes de ser chamada a operação de Alteração,
     * para que o formulário apareça todo preenchido.
     *
     * FIX ME!!!!
     * Como saber realmente se a PJ está logada? é preciso fazer essa verificação?
     */
    private class PreencherTodoCadPJHandler extends SACHandler {
      private static final String URL_CADASTRO_PJ = "/cadastroPJ.jsp";
      private static final String CADASTRO_PJ_BEAN_REQUEST = "cadastroPJ";

      /** 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 {

        CadastroPJBean cadastroPJ = new CadastroPJBean();

        try {
            OID oid = (OID) request.getSession().getAttribute(this.OID_SESSION);
            PessoaJuridica pessoa = (PessoaJuridica) fachada.procuraUsuario(oid, UsuarioComum.STATUS_PESSOA_JURIDICA);

            cadastroPJ = new CadastroPJBean(pessoa);

            System.out.println(pessoa);

            cadastroPJ.setOperation(OPERACAO_ALTERACAO);
            request.setAttribute(CADASTRO_PJ_BEAN_REQUEST, cadastroPJ);

          } catch (PersistenceException pe) {
            cadastroPJ.setErroPersistencia("Problemas na conexão com o BD");
            request.setAttribute(CADASTRO_PJ_BEAN_REQUEST, cadastroPJ);
          } catch (ItemNaoCadastradoException ince) {
            // Vai acontecer?
            // Ver comentario da classe...
            ince.printStackTrace();
          } catch (InvalidArgumentException iae) {
            iae.printStackTrace();
          }

          return URL_CADASTRO_PJ;
      }
    }

}