package com.handong.smartservice.service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.handong.smartservice._AG;
import com.handong.smartservice.component.CtResponse;
import com.handong.smartservice.component.DbLogger;
import com.handong.smartservice.component.ErrorCode;
import com.handong.smartservice.component.UserInfo;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import com.handong.smartservice.mapper.AccountMapper;


@Service
public class AccountService {
    private final AccountMapper accountMapper;
    private final PasswordEncoder passwordEncoder;

    public AccountService(AccountMapper accountMapper, PasswordEncoder passwordEncoder) {
        this.accountMapper = accountMapper;
        this.passwordEncoder = passwordEncoder;
    }

    public CtResponse getAccount(Long gid, String user_id) {
        CtResponse result = new CtResponse();
        if (gid != 0L && user_id != null && user_id.isEmpty()) {
            result.setErrCode(ErrorCode.INVALID_PARAMETER);
            return result;
        }

        List<Map<String, Object>> listMap = (List<Map<String, Object>>)accountMapper.selectAccount(false, false, 0L, 1L,
                null, null, gid, user_id, null, null, 0L);
        
        if (listMap.size() == 0)
            result.put("result", null);
        else
            result.put("result", listMap.get(0));

        return result;
    }

    public Map<String, Object> getAccountList(Long offset, Long limit, String date_start, String date_end, Boolean is_excel, Boolean is_group_access, String user_id, String email, String nick_name, Long biz_group_id) {
        Map<String, Object> mapResult = new HashMap<>();

        //if (is_group_access) {

        List<Map<String, Object>> listMap = (List<Map<String, Object>>)accountMapper.selectAccount2(false, offset, limit,
                date_start, date_end, is_excel, 0L, user_id, email, nick_name, biz_group_id);
        mapResult.put("list", listMap);

        Long totalCount = _AG.getNumberFromQuery("COUNT(*)", accountMapper.selectAccount2(true, offset, limit,
                date_start, date_end, is_excel, 0L, user_id, email, nick_name, biz_group_id));
        mapResult.put("totalCount", totalCount);
        mapResult.put("offset", offset);
        return mapResult;
    }

    public CtResponse addOrModifyAccount(boolean isModify, Long gid, String user_id, String user_pw, String email, String nick_name, Long state, Long biz_group_id, Long new_biz_group_id) {
        CtResponse result = new CtResponse();

        UserInfo userInfo = (UserInfo)SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        String enc_pw = passwordEncoder.encode(user_pw);

        if (new_biz_group_id != 0 && new_biz_group_id != biz_group_id)
            biz_group_id = new_biz_group_id;

        if (isModify) {
            if (gid == 0) {
                result.setErrCode(ErrorCode.INVALID_PARAMETER);
                return result;
            }

            //accountMapper.updateAccount(gid, user_pw, nick_name, email, state, biz_group_id);
            accountMapper.updateAccount(gid, enc_pw, nick_name, email, state, biz_group_id);
            DbLogger.insert(2L, "계정정보 수정", userInfo.getGid());
        }
        else {
            if (user_id == null || user_id.isEmpty()) {
                result.setErrCode(ErrorCode.INVALID_PARAMETER);
                return result;
            }

            Map<String, Object> params = new HashMap<>();
            params.put("user_id", user_id);
            //params.put("user_pw", user_pw);
            params.put("user_pw", enc_pw);
            params.put("nick_name", nick_name);
            params.put("email", email);
            params.put("state", state);
            params.put("biz_group_id", biz_group_id);

            if (biz_group_id == 667)    //TempCode
                params.put("permission", 1L);
            else 
                params.put("permission", 2L);

            if (accountMapper.insertAccount(params) == 0) {
                result.setErrCode(ErrorCode.INVALID_PARAMETER);
            }
            else {
                DbLogger.insert(2L, "신규 계정 추가, id: " + user_id, userInfo.getGid());
                //result.put("result", Map.of("gid", params.get("gid")));
                Map<String, Object> ret = new HashMap<String, Object>();
                ret.put("gid", params.get("gid"));
                result.put("result", ret);
            }
        }

        return result;
    }

    public CtResponse removeAccount(String ids) {
        CtResponse result = new CtResponse();

        List<Long> arrId = Arrays.stream(ids.split(","))
            .map(Long::parseLong)
            .collect(Collectors.toList());
        
        int changed = accountMapper.changeState(arrId, 2);
        if (changed == 0) {
            result.setErrCode(ErrorCode.QUERY_ERROR);
        }
        DbLogger.insert(2L, "계정 삭제, id: " + ids, 2L);
        
        return result;
    }
}
