package com.lemon.lifecenter.controller;

import java.util.HashMap;

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

import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.lemon.lifecenter.common.LifeCenterConfigVO;
import com.lemon.lifecenter.common.LifeCenterController;
import com.lemon.lifecenter.common.LifeCenterFunction;
import com.lemon.lifecenter.common.LifeCenterSessionController;
import com.lemon.lifecenter.dto.LoginDTO;
import com.lemon.lifecenter.service.LoginService;

@Controller
@RequestMapping("/login")
public class LoginController extends LifeCenterController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Autowired
    LifeCenterConfigVO config;
    
    @Autowired
    LoginService loginService;
    
    @RequestMapping("/admin")
    public ModelAndView adminLogin() {
        ModelAndView mv = setMV("login/admin");

        return mv;
    }

    @RequestMapping("/staff")
    public ModelAndView staffLogin() {
        ModelAndView mv = setMV("login/staff");

        return mv;
    }
    
    
    @RequestMapping( value="/check", method = RequestMethod.POST )
    @ResponseBody
    public String staffLoginCheck( 
            @ModelAttribute("dto") final LoginDTO dto, 
            HttpServletRequest request, HttpServletResponse response ) throws Exception {
        String remoteIp   = LifeCenterFunction.getRemoteAddr( request );
        String resultCode = "";
        String message    = "";
        
        HashMap<String, String> accessMap = new HashMap<String, String>();
        JSONObject json = new JSONObject();
        
        dto.setPassword( LifeCenterFunction.aesEncrypt( config.aesKey, config.IV, dto.getPassword() ) );
        
        int total = loginService.selectMemberCount( dto );
        
        if( total == 0 ) { //로그인실패시 log 남긴 후 failCount 처리
            
            resultCode = "01";
            message    = "아이디 또는 비밀번호를 다시 확인하세요.<br/>등록되지 않은 사용자이거나, 잘못된 비밀번호입니다.";
            
            logger.error( "[LOGIN FAILED] RemoteIP : " + remoteIp + " ID : " + dto.getId() + "MESSAGE : " + LifeCenterFunction.removeTag( message ) );
            
            if( loginService.selectMemberIdCount( dto ) == 1 ) { //존재하는사용자일경우
                dto.setFailCount( loginService.selectMemberFailCount( dto ) + 1 ); //해당아이디의 failCount + 1
                dto.setResultCode( resultCode );
                
                accessMap.put( "id" , dto.getId() );
                accessMap.put( "ip" , remoteIp );
                accessMap.put( "successYn", "N" );
                accessMap.put( "logMessage" , LifeCenterFunction.removeTag( message ) );
                
                loginService.updateMemberLoginData( dto ); //해당 아이디의 failCount
                loginService.insertAccessHistory( accessMap );
            }
        } else { // 로그인 성공시 ( id, password 일치 )
            LoginDTO memberData = loginService.selectMemberData( dto );
            
            accessMap.put( "id" , dto.getId() );
            accessMap.put( "ip" , remoteIp );
            
            if( memberData.getUseYn().toUpperCase().equals( "N" ) ) { // 사용이 중지된 계정
                logger.error( "[LOGIN FAILED] RemoteIP : " + remoteIp + " ID : " + dto.getId() );
                
                resultCode = "02";
                message    = "사용이 중지된 계정입니다. 관리자에게 문의하세요.";
                
                accessMap.put( "successYn", "N" );
                accessMap.put( "logMessage" , message );
                
                logger.error( "[LOGIN FAILED] RemoteIP : " + remoteIp + " ID : " + dto.getId() + "MESSAGE : " + message );
                
                loginService.insertAccessHistory( accessMap );
                
            } else {
                // 로그인 성공
                // failCount 0 초기화
                // last login time NOW() update
                resultCode = "00";
                message    = "로그인 성공";
                
                dto.setFailCount( 0 );
                accessMap.put( "successYn", "Y" );
                accessMap.put( "logMessage" , message );
                
                logger.info( "[LOGIN SUCCESS] RemoteIP : " + remoteIp + " ID : " + dto.getId() + "MESSAGE : " + message );
                
                loginService.updateMemberLoginData( dto ); //failCount -> 0, lastLoginTime -> NOW()
                loginService.insertAccessHistory( accessMap ); //insert AccessHistory
                
                
                LifeCenterSessionController.sessionInvalidate( request );
                
                LifeCenterSessionController.setSession( request, "sesId",   memberData.getId().toLowerCase() );
                LifeCenterSessionController.setSession( request, "sesName", memberData.getName() );
                LifeCenterSessionController.setSession( request, "sesCenterCode", memberData.getCenterCode() );
                LifeCenterSessionController.setSession( request, "sesGroupIdx", String.valueOf( memberData.getGroupIdx() ) );
            }
        }
        
        json.put( "code", resultCode );
        json.put( "message", message );
        
        System.out.println( "JSON : " + json );
        
        return json.toString();
    }
    
    @RequestMapping("/logout")
    public String staffLogout( HttpServletRequest request, HttpServletResponse response ) {
        String remoteIp  = LifeCenterFunction.getRemoteAddr( request );
        String sesId     = LifeCenterSessionController.getSession( request, "sesId" );
        
        LifeCenterSessionController.sessionInvalidate( request );
        
        logger.error( "[LOGOUT] RemoteIP : " + remoteIp + " UserId : " + sesId );
        
        return "redirect:/login/staff";
    }
}
