package com.yeejoin.precontrol.controller.publics;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.typroject.tyboot.core.foundation.context.RequestContext;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yeejoin.amos.component.feign.config.InnerInvokException;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.privilege.model.DepartmentModel;
import com.yeejoin.amos.feign.privilege.model.RoleModel;
import com.yeejoin.precontrol.common.entity.Company;
import com.yeejoin.precontrol.common.entity.Person;
import com.yeejoin.precontrol.common.entity.PersonAscription;
import com.yeejoin.precontrol.common.exception.BaseException;
import com.yeejoin.precontrol.common.service.ICompanyService;
import com.yeejoin.precontrol.common.service.IPersonAscriptionService;
import com.yeejoin.precontrol.common.service.IPersonService;
import com.yeejoin.precontrol.common.utils.PlatformUtils;
import com.yeejoin.precontrol.common.utils.RedisUtil;
import com.yeejoin.precontrol.common.vo.ReginParams;

import lombok.extern.slf4j.Slf4j;
import springfox.documentation.annotations.ApiIgnore;

/**
 * 基础控制器
 *
 * @author
 */
@ApiIgnore
@RestController(value = "BaseController")
@RequestMapping("/base")
//@Authorization
@Slf4j
@Primary
public class BaseController {

	/**
	 * 成功返回状态
	 */
	protected static final String SUCCESS = "SUCCESS";
	/**
	 * 失败返回状态
	 */
	protected static final String FAILED = "FAILED";
	/**
	 * 默认页大小
	 */
	protected static final int DEFAULT_PAGE_SIZE = 10;
	@Autowired
	protected HttpServletRequest request;
	@Autowired
	private RedisTemplate<String, String> redisTemplate;
	@Autowired
	private IPersonService personService;
	@Autowired
	private IPersonAscriptionService ascriptionService;
	@Autowired
	private ICompanyService companyService;
	@Autowired
	private PlatformUtils platformUtils;

	/**
	 * 产品号
	 */
	@Value("${admin.product}")
	String product;
	/**
	 * 产品密钥
	 */
	@Value("${admin.appkey}")
	String appkey;

	/**
	 * 账户
	 */
	@Value("${admin.user}")
	String user;
	/**
	 * 密码
	 */
	@Value("${admin.password}")
	String password;

	@Value("${amos.secret.key}")
	String secretKey;

	@Autowired
	RedisUtil redisUtil;

	protected String getToken() {
		String authToken = request.getHeader("token");
		if (authToken == null) {
			authToken = request.getHeader("X-Access-Token");
		}
		return authToken;
	}

	protected String getProduct() {
		String authToken = request.getHeader("product");
		if (authToken == null) {
			authToken = request.getParameter("product");
		}
		return authToken;
	}

	protected String getAppKey() {
		String authToken = request.getHeader("appKey");
		if (authToken == null) {
			authToken = request.getParameter("appKey");
		}
		return authToken;
	}

	protected ReginParams getReginInfo() {
		String token = getToken();
		log.info("token-------------------->:" + getToken());
		if (StringUtils.isEmpty(token)) {
			throw new BaseException("token为空!");
		}
		AgencyUserModel userInfo = getUserInfo();
		if (userInfo == null) {
			log.info("请求平台用户为空");
			return null;
		}
		Long userId = userInfo.getSequenceNbr();
		if (redisUtil.hasKey(userId + "_" + getToken())) {
			ReginParams reginParams = (ReginParams) redisUtil.get(userId + "_" + getToken());
			log.info("user------------------>获取缓存用户信息成功");
			return reginParams;
		}
		ReginParams reginParams = new ReginParams();
		Person curPerson = personService
				.getOne(new QueryWrapper<Person>().lambda().eq(Person::getId, userInfo.getSequenceNbr()));
		if (curPerson == null) {
			log.info("当前用户未绑定平台,请绑定平台");
			return null;
		}
		reginParams.setPerson(curPerson);
		// 获取用户角色
		Map<Long, List<RoleModel>> orgRoles = userInfo.getOrgRoles();
		if (orgRoles != null) {
			Set<Long> keySet = orgRoles.keySet();
			if (!keySet.isEmpty()) {
				List<RoleModel> list = orgRoles.get(keySet.iterator().next());
				RoleModel roleModel = list.get(0);
				reginParams.setRole(roleModel);
			}
		}
		// 查询用户所属信息
		PersonAscription ascription = ascriptionService.getOne(
				new QueryWrapper<PersonAscription>().lambda().eq(PersonAscription::getPersonId, curPerson.getId()));
		if (ascription != null) {
			Company company = companyService.getById(ascription.getCompanyId());
			reginParams.setCompany(company);
		}
		redisUtil.set(userId + "_" + getToken(), reginParams, 60);
		return reginParams;
	}

	/**
	 * <pre>
	 * 判断当前用户是否为分包商角色：true:分包商/false:江西电建
	 * </pre>
	 *
	 * @return
	 */
	protected boolean isFbsRole(ReginParams reginParams) {
		if (reginParams != null) {
			if (reginParams.getRole() != null) {
				String roleType = reginParams.getRole().getRoleType();
				if (roleType != null && "fbs".equals(roleType)) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 当前登录用户信息
	 */
	protected AgencyUserModel getUserInfo() {
		AgencyUserModel agencyUserModel = new AgencyUserModel();
		String token = getToken();
		if (token != null) {
			String product = getProduct();
			String appKey = getAppKey();
			RequestContext.setToken(token);
			RequestContext.setProduct(product);
			RequestContext.setAppKey(appKey);
			FeignClientResult<AgencyUserModel> feignClientResult;
			try {
				feignClientResult = Privilege.agencyUserClient.getme();
				try {
					agencyUserModel = feignClientResult.getResult();
					if (agencyUserModel != null) {
						log.info("请求平台用户数据,数据result返回:{}", agencyUserModel.toString());
					}
				} catch (Exception e) {
					log.info("请求平台用户数据,对象转换错误 AgencyUserModel-result error:{}", e.toString());
					// throw new BaseException("请求平台用户数据,数据转换错误！");
				}
			} catch (Exception e) {
				if (e instanceof InnerInvokException) {
					int httpStatus = ((InnerInvokException) e).getHttpStatus();
					// throw new BaseException(httpStatus, "请求平台用户信息接口错误:" + e.getMessage());
				}
				// throw new BaseException("请求平台用户信息接口失败:" + e.getMessage());
				log.error("请求平台用户信息接口失败");
			}
		} else {
			log.error("token为空!!!!!!!!!!!!!!!!!!!!!!!!!!!");
		}
		return agencyUserModel;
	}

	protected String getUserId() {
		String userId = null;
		if (getUserInfo() != null) {
			userId = getUserInfo().getUserId();
		}
		return userId;
	}

	protected Long getCompanyId(ReginParams reginParams) {
		if (reginParams == null) {
			return null;
		}
		if (reginParams.getCompany() != null) {
			return reginParams.getCompany().getId();
		}
		return null;
	}

	/**
	 * 获取请求的cookies
	 *
	 * @return
	 */
	protected HashMap<String, String> getCookInfoMap() {
		HashMap<String, String> map = new HashMap<String, String>();
		Cookie[] cookies = request.getCookies();
		if (cookies != null) {
			for (Cookie ck : cookies) {
				map.put(ck.getName(), ck.getValue());
			}
		}
		return map;
	}

	/**
	 * 获取平台绑定的用户信息
	 *
	 * @return
	 */
	public Person getPerson() {
		ReginParams reginInfo = getReginInfo();
		Person person;
		if (reginInfo != null) {
			person = reginInfo.getPerson();
		} else {
			person = new Person();
		}
		return person;
	}

	public DepartmentModel getDepartment(Long departmentId) {
		String token = getToken();
		String product = getProduct();
		String appKey = getAppKey();
		RequestContext.setToken(token);
		RequestContext.setProduct(product);
		RequestContext.setAppKey(appKey);
		FeignClientResult<DepartmentModel> departmentModel = Privilege.departmentClient.seleteOne(departmentId);
		return departmentModel.getResult();
	}

	protected void buildRequestContext() {
		String token = getToken();
		String product = getProduct();
		String appKey = getAppKey();
		RequestContext.setToken(token);
		RequestContext.setProduct(product);
		RequestContext.setAppKey(appKey);
	}

	/**
	 * 设置平台接口调用权限
	 */
	public void setPlatFormAccess() {
		platformUtils.setPlatFormAccess();
	}
}
