package com.palmnest.webapp.controller.api;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.palmnest.application.AppConstants;
import com.palmnest.application.bean.AppResultDto;
import com.palmnest.application.core.util.*;
import com.palmnest.application.dto.IndexMenuDto;
import com.palmnest.application.dto.MenuDto;
import com.palmnest.application.dto.UserDto;
import com.palmnest.model.AppUserOrgnizationRelation;
import com.palmnest.model.User;
import com.palmnest.model.estateserve.SmsAuthCode;
import com.palmnest.model.property.TbOrganization;
import com.palmnest.model.repair.RepairConfig;
import com.palmnest.service.AppMenuService;
import com.palmnest.service.AppUserService;
import com.palmnest.service.OrganizationManager;
import com.palmnest.service.UserManager;
import com.palmnest.service.estateserve.SmsAuthCodeManager;
import com.palmnest.service.redis.BaseRedisService;
import com.palmnest.service.repair.RepairBillService;
import com.palmnest.service.repair.RepairConfigManager;
import com.palmnest.webapp.controller.BaseFormController;
import com.palmnest.webapp.filter.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

@Slf4j
@Controller
@RequestMapping("/api/user")
public class ApiUserController extends BaseFormController {


	public static String wjx_service_url = PropertiesKit.readPropertiesValue("wjx_service_url", "wechat.properties");

	@Autowired
	private UserManager         userManager;
	@Autowired
	private AppUserService      appUserService;
	@Autowired
	private PasswordEncoder     passwordEncoder;
	@Autowired
	private BaseRedisService    baseRedisService;
	@Autowired
	private AppMenuService      appMenuService;
	@Autowired
	private SmsAuthCodeManager  smsAuthCodeManager;
	@Autowired
	private OrganizationManager organizationManager;
	//dz add
	@Autowired
	private RepairConfigManager repairConfigManager;
	@Autowired
	private RepairBillService   repairBillService;
	private long                time = 60 * 60 * 24 * 7;//7天有效

	@RequestMapping("/login")
	@ResponseBody
	public AppResultDto login(String userName, String password, Integer deviceType, @RequestParam(required = false) String deviceNo) {
		if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(password)) {
			return AppResultUtil.createErrorDto(AppConstants.USER_NAME_OR_PASSWORD_NULL, "用户名或密码为空");
		}
		User user = userManager.getUserByUsername2(userName);
		//根据电话号码登录
		if (user == null) {
			user = userManager.findByTelephone(userName);
		}
		if (user == null) {
			return AppResultUtil.createErrorDto(AppConstants.USER_NOT_EXIST, "用户不存在");
		}
		if (!passwordEncoder.encodePassword(password, user.getUsername().toLowerCase()).equals(user.getPassword())) {
			return AppResultUtil.createErrorDto(AppConstants.PASSWORD_ERROR, "密码错误");
		}
		user.setDeviceType(deviceType);
		user.setDeviceNo(deviceNo);
		userManager.save(user);
		String token    = JwtUtil.getToken(user.getUsername());
		String oldToken = baseRedisService.get(user.getUsername());
		if (oldToken != null) {
			baseRedisService.dele(oldToken);
			baseRedisService.dele(user.getUsername());
		}
		baseRedisService.set(user.getUsername(), token, time);
		baseRedisService.set(token, user.getUsername(), time);

		//redis缓存当前登录用户的管辖项目
		String orgIds = baseRedisService.get(AppConstants.USERMANAGEORG + user.getId());
		if (StringUtils.isBlank(orgIds)) {
			List<TbOrganization> list = organizationManager.getUserRelationOrganizationList(user.getId());
			//构建json数组存入项目id与名称
			JSONArray jsonArray = new JSONArray();
			for (TbOrganization t : list) {
				JSONObject obj = new JSONObject();
				obj.put("id", t.getId());
				obj.put("name", t.getName());
				jsonArray.add(obj);
			}
			//存入redis缓存 对应key为: userManageOrg_userId
			baseRedisService.set(AppConstants.USERMANAGEORG + user.getId(), jsonArray.toJSONString());
		}

		UserDto dto = appUserService.convertDto(user);
		dto.setRoles(user.getRoles());
		dto.setToken(token);

		List<AppUserOrgnizationRelation> orgList = userManager.getAppUserOrgByUserId(Integer.parseInt(user.getId().toString()));
		if (orgList != null && orgList.size() > 0) {
			AppUserOrgnizationRelation orgRe = orgList.get(0);
			if (orgRe != null) {
				TbOrganization org = organizationManager.getOrganizationById(orgRe.getOrgId());
				if (org != null) {
					dto.setOrgId(org.getId().toString());
					dto.setOrgName(org.getName());
					dto.setHotline(org.getTelephone());
					dto.setMeetClient(org.getMettingClient());
				}
			}
		}
		//add dz 1030 工程维修模式
		dto.setRepairMode(0);
		if (StringUtils.isNotEmpty(dto.getOrgId())) {
			RepairConfig s_con = repairConfigManager.getByOrgId(Integer.parseInt(dto.getOrgId()));
			if (s_con != null) {
				dto.setRepairMode(s_con.getRepair_type());
				dto.setRepairPersons(s_con.getIspersons().intValue());
				dto.setRepairPay(s_con.getIspay() == 1 ? 1 : 0);
			} else {
				dto.setRepairMode(1);
				dto.setRepairPersons(2);
				dto.setRepairPay(1);
			}
		}

		return AppResultUtil.createSuccesDto("登录成功", dto);
	}


	@RequestMapping("/menuList")
	@ResponseBody
	public AppResultDto menuList(HttpServletRequest request) {
		String userName = baseRedisService.get(request.getHeader("token"));
		if (userName == null) {
			AppResultDto rt = AppResultUtil.createErrorDto(AppConstants.TOKEN_EXPIRED, "token已过期");
			return rt;
		}
		List<MenuDto> dtos = appMenuService.findMenuDto(userName);
		return AppResultUtil.createSuccesDto("查询成功", dtos);
	}

	/**
	 * 新版APP首页菜单列表
	 *
	 * @param request
	 * @return
	 */
	@RequestMapping("/indexMenuList")
	@ResponseBody
	public AppResultDto indexMenuList(HttpServletRequest request) {
		String token    = request.getHeader("token");
		String userName = baseRedisService.get(request.getHeader("token"));
		User   user     = userManager.getUserByUsername2(userName);
		String orgIds   = getUserManageOrgIds(user);
		if (userName == null) {
			AppResultDto rt = AppResultUtil.createErrorDto(AppConstants.TOKEN_EXPIRED, "token已过期");
			return rt;
		}
		List<IndexMenuDto> dtos = appMenuService.findIndexMenus(userName, false, orgIds, token);
		return AppResultUtil.createSuccesDto("查询成功", dtos);
	}

	/**
	 * 新版APP首页子菜单列表
	 *
	 * @param request
	 * @return
	 */
	@RequestMapping("/childrenMenuList")
	@ResponseBody
	public AppResultDto childrenMenuList(Integer parentId, HttpServletRequest request) throws Exception {
		String token    = request.getHeader("token");
		String userName = baseRedisService.get(token);
		if (userName == null) {
			AppResultDto rt = AppResultUtil.createErrorDto(AppConstants.TOKEN_EXPIRED, "token已过期");
			return rt;
		}
		User               user   = userManager.getUserByUsername2(userName);
		String             orgIds = getUserManageOrgIds(user);
		List<IndexMenuDto> dtos   = appMenuService.findMenusByParent(parentId, user, orgIds, token);
		return AppResultUtil.createSuccesDto("查询成功", dtos);
	}


	@RequestMapping("/uploadPhoto")
	@ResponseBody
	public AppResultDto uploadPhoto(MultipartHttpServletRequest request) {
		String userName = baseRedisService.get(request.getHeader("token"));
		if (userName == null) {
			AppResultDto rt = AppResultUtil.createErrorDto(AppConstants.TOKEN_EXPIRED, "token已过期");
			return rt;
		}
		MultipartFile file = request.getFile("file");
		if (file == null) {
			return AppResultUtil.createErrorDto(AppConstants.UPLOAD_PHOTO_ERROR, "请选择头像");
		}

		//获得文件原始名称
		try {
			InputStream stream   = null;
			String      fileExt  = null;
			String      fileName = "";
			if (file != null) {
				stream = file.getInputStream();
				fileName = file.getOriginalFilename();
				fileName = new String(fileName.getBytes(), "utf-8");
				fileExt = StringUtils.isNotEmpty(fileName) ? fileName
						.substring(fileName.lastIndexOf("."))
						: StringUtils.EMPTY;
			}

			FileUploadUtils fileUploadUtils = new FileUploadUtils();
			fileUploadUtils.init();
			String url       = fileUploadUtils.uploadFile(stream, fileExt);
			String picUrl    = fileUploadUtils.fullVisitPath(url);
			User   user      = userManager.getUserByUsername2(userName);
			String oldPicUrl = user.getPhotoUrl();
			user.setPhotoUrl(picUrl);
			userManager.updateModel(user);
			//删除原来的头像
			if (oldPicUrl != null && !oldPicUrl.equals("")) {
				FileUploadUtils.deleteFileByPath(oldPicUrl);
			}
			return AppResultUtil.createSuccesDto(picUrl);
		} catch (IOException e) {
			e.printStackTrace();
			return AppResultUtil.createErrorDto(AppConstants.UPLOAD_PHOTO_ERROR, "上传头像失败");
		}
	}

	@RequestMapping("/modifyPassword")
	@ResponseBody
	public AppResultDto modifyPassword(String oldPwd, String newPwd, HttpServletRequest request) {
		String userName = baseRedisService.get(request.getHeader("token"));
		if (userName == null) {
			AppResultDto rt = AppResultUtil.createErrorDto(AppConstants.TOKEN_EXPIRED, "token已过期");
			return rt;
		}
		//修改密码
		try {
			if (StringUtils.isBlank(oldPwd)) {
				return AppResultUtil.createErrorDto(AppConstants.MODIFY_PWD_ERROR, "请输入原始密码");
			}
			if (StringUtils.isBlank(newPwd)) {
				return AppResultUtil.createErrorDto(AppConstants.MODIFY_PWD_ERROR, "请输入新密码");
			}
			boolean retFlag = userManager.updateUserPwd(userName, oldPwd, newPwd);
			User    user    = userManager.getUserByUsername2(userName);
			if (retFlag) {
				return AppResultUtil.createSuccesDto(appUserService.convertDto(user));
			} else {
				return AppResultUtil.createErrorDto(AppConstants.MODIFY_PWD_ERROR, "密码修改失败，原始密码错误，请检查.");
			}
		} catch (Exception e) {
			e.printStackTrace();
			return AppResultUtil.createErrorDto(AppConstants.MODIFY_PWD_ERROR, "修改密码失败");
		}
	}


	@RequestMapping("/loginOut")
	@ResponseBody
	public AppResultDto loginOut(HttpServletRequest request) {
		try {
			//token
			String token    = request.getHeader("token");
			String userName = baseRedisService.get(token);
			baseRedisService.dele(userName);
			baseRedisService.dele(token);
			//机器码清空
			User user = userManager.getUserByUsername2(userName);
			if (user != null) {
				user.setDeviceNo(null);
				user.setDeviceType(null);
				userManager.updateModel(user);
			}
			return AppResultUtil.createSuccesDto();
		} catch (Exception e) {
			e.printStackTrace();
			return AppResultUtil.createErrorDto(AppConstants.LOGIN_OUT_ERROR, "退出登录失败");
		}
	}

	/**
	 * 签到
	 *
	 * @param request
	 * @return
	 */
	@RequestMapping("/checkIn")
	@ResponseBody
	public AppResultDto checkIn(HttpServletRequest request) {
		try {
			String userName = baseRedisService.get(request.getHeader("token"));
			User   user     = userManager.getUserByUsername2(userName);
			user.setIsOnline(2);
			userManager.updateModel(user);
			return AppResultUtil.createSuccesDto();
		} catch (Exception e) {
			e.printStackTrace();
			return AppResultUtil.createErrorDto(AppConstants.CHECK_IN_ERROR, "签到失败");
		}
	}

	/**
	 * 签退
	 *
	 * @param request
	 * @return
	 */
	@RequestMapping("/checkOut")
	@ResponseBody
	public AppResultDto checkOut(HttpServletRequest request) {
		try {
			String userName = baseRedisService.get(request.getHeader("token"));
			User   user     = userManager.getUserByUsername2(userName);
			user.setIsOnline(1);
			userManager.updateModel(user);
			return AppResultUtil.createSuccesDto();
		} catch (Exception e) {
			e.printStackTrace();
			return AppResultUtil.createErrorDto(AppConstants.CHECK_OUT_ERROR, "签退失败");
		}
	}

	/**
	 * 获取验证码接口
	 *
	 * @return
	 */
	@RequestMapping(value = "/getAuthCode")
	@ResponseBody
	public AppResultDto authCode(@RequestParam String telephone) {
		String result = "Error";
		if (StringUtils.isEmpty(telephone) || !RegularPattern.isMobileNO(telephone)) {
			return AppResultUtil.createErrorDto(AppConstants.GET_CODE_ERROR, "请输入正确的电话号码");
		}
		if (StringUtils.isNotBlank(telephone)) {
			User user = userManager.findByTelephone(telephone);
			if (user == null) {
				return AppResultUtil.createErrorDto(AppConstants.GET_CODE_ERROR, "电话号码对应的用户不存在");
			}
			String code    = NumberUtils.getValidateCode();
			String content = "您的验证码为" + code + "，15分钟内有效，如非本人操作，请忽略。";
			//发送短信
//			result=smsAuthCodeManager.sendSms(telephone, content);
			result = smsAuthCodeManager.smsSendByOrgId("0", content, telephone, code, 1);
			if ("Success".equals(result.trim())) {
				return AppResultUtil.createSuccesDto();
			}
		}
		return AppResultUtil.createErrorDto(AppConstants.GET_CODE_ERROR, "获取验证码失败");
	}

	@RequestMapping("/resetPassword")
	@ResponseBody
	public AppResultDto resetPassword(String telephone, String authCode, String newPwd) {
		//重置密码
		try {
			if (StringUtils.isBlank(authCode)) {
				return AppResultUtil.createErrorDto(AppConstants.REST_PASSWORD_ERROR, "请输入验证码");
			}
			if (StringUtils.isBlank(newPwd)) {
				return AppResultUtil.createErrorDto(AppConstants.REST_PASSWORD_ERROR, "请输入新密码");
			}
			SmsAuthCode smsAuthCode = smsAuthCodeManager.getSmsAuthCode(telephone, authCode, "1", 15);
			if (smsAuthCode == null) {
				return AppResultUtil.createErrorDto(AppConstants.AUTH_CODE_ERROR, "验证码不正确");
			}
			User user = userManager.findByTelephone(telephone);
			if (user == null) {
				return AppResultUtil.createErrorDto(AppConstants.REST_PASSWORD_ERROR, "电话号码对应的用户不存在");
			}
			boolean retFlag = userManager.resetUserPwd(user.getUsername(), newPwd);
			if (retFlag) {
				return AppResultUtil.createSuccesDto(appUserService.convertDto(user));
			} else {
				return AppResultUtil.createErrorDto(AppConstants.REST_PASSWORD_ERROR, "重置密码失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
			return AppResultUtil.createErrorDto(AppConstants.REST_PASSWORD_ERROR, "重置密码失败");
		}
	}

	/**
	 * 更新机器码
	 *
	 * @param request
	 * @return
	 */
	@RequestMapping("/updateDeviceNo")
	@ResponseBody
	public AppResultDto updateDeviceNo(Integer deviceType, String deviceNo, HttpServletRequest request) {
		try {
			String userName = baseRedisService.get(request.getHeader("token"));
			User   user     = userManager.getUserByUsername2(userName);
			user.setDeviceType(deviceType);
			user.setDeviceNo(deviceNo);
			;
			userManager.updateModel(user);
			return AppResultUtil.createSuccesDto(appUserService.convertDto(user));
		} catch (Exception e) {
			e.printStackTrace();
			return AppResultUtil.createErrorDto(AppConstants.UPDATE_DEVICENO_ERROR, "更新设备码失败");
		}
	}
}
