package com.uas.sso.controller;

import java.io.IOException;

import javax.validation.Valid;

import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
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.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.uas.account.AccountConfig;
import com.uas.account.core.Page;
import com.uas.account.core.Status;
import com.uas.account.core.util.ExecuteUtils;
import com.uas.account.entity.ChangeAdminDetail;
import com.uas.account.entity.Setting;
import com.uas.account.entity.Token;
import com.uas.account.service.ChangeAdminService;
import com.uas.account.service.SettingService;
import com.uas.account.service.TokenService;
import com.uas.account.web.BaseController;
import com.uas.dfs.service.FileClient;
import com.uas.message.mail.service.MailService;
import com.uas.message.sms.service.SmsService;
import com.uas.sso.SSOHelper;
import com.uas.sso.web.waf.request.WafRequestWrapper;

@Controller
@RequestMapping("/changeAdmin")
public class ChangeAdminController extends BaseController {

	@Autowired
	private ChangeAdminService changeAdminService;

	@Autowired
	private FileClient fileClient;

	@Autowired
	private MailService mailService;

	@Autowired
	private SmsService smsService;

	@Autowired
	private SettingService settingService;

	@Autowired
	private TokenService tokenService;

	/**
	 * 上传营业执照附件
	 * 
	 * @param detail
	 * @param result
	 * @param file
	 * @return
	 */
	@RequestMapping(value = "/userspace/changeAdmin", method = RequestMethod.POST)
	@ResponseBody
	public ModelMap submit(final @Valid ChangeAdminDetail detail, BindingResult result,
			@RequestBody MultipartFile file) {
		if (result.hasErrors()) {
			return error(result.getFieldErrors());
		}
		if (file == null || file.isEmpty()) {
			return error("请上传营业执照附件");
		}
		if (file.getSize() > 5242880) {
			return error("营业执照附件大小不要超过5M");
		}
		try {
			String path = fileClient.upload(file.getBytes(), file.getSize(),
					FilenameUtils.getExtension(file.getOriginalFilename()), null);
			if (path != null) {
				detail.setBusinessCodeImage(path);
				try {
					changeAdminService.submit(detail);
				} catch (Exception e) {
					fileClient.delete(path);
					throw e;
				}
			} else {
				return error("请检查您的营业执照附件");
			}
		} catch (IOException e) {
			return error("请检查您的营业执照附件");
		}
		request.getSession().setAttribute("pageStep", 2);
		// 知会下审核人
		ExecuteUtils.asyncExecute(new Runnable() {

			@Override
			public void run() {
				// 邮件
				Setting mailReceiver = settingService.findOne("mailReceiverAfterRegister");
				Setting mailTpl = settingService.findOne("noticeManageAuditVendorMan");
				if (mailReceiver != null && mailTpl != null) {
					ModelMap data = new ModelMap();
					data.put("adminName", detail.getAdminName());
					data.put("enlicense", detail.getBusinessCode());
					mailService.send(mailTpl.getValue(), mailReceiver.getValue(), data);
				}
				// 短信
				Setting smsReceiver = settingService.findOne("SmsNoticeManageAuditVendorMan");
				Setting smsTpl = settingService.findOne("noticeManageAuditVendorMan");
				if (smsReceiver != null && smsTpl != null) {
					smsService.send(smsTpl.getValue(), smsReceiver.getValue(), new Object[] { detail.getAdminName() });
				}
			}
		});
		return success();
	}

	/**
	 * 更换管理员
	 * 
	 * @throws Exception
	 */
	@RequestMapping(value = "/changeAdmin", method = RequestMethod.GET)
	public ModelAndView changeAdminPage(ModelMap model) throws Exception {
		// 先清除可能存在的登录状态
		SSOHelper.clearLogin(request, response);

		WafRequestWrapper wr = new WafRequestWrapper(request);
		String tokenId = wr.getParameter("token");
		if (!StringUtils.isEmpty(tokenId)) {
			Token token = tokenService.findOne(tokenId);
			if (token == null || token.isExpired()) {
				return new ModelAndView("changeAdmin/error", error("您的邮件已经失效"));
			}
			final ChangeAdminDetail detail = changeAdminService.findByBusinessCode(token.getBind().toString());
			if (detail == null) {
				return new ModelAndView("changeAdmin/error", error("您的申请已失效，请重新申请"));
			} else {
				tokenService.delete(token.getId());
				// 页面token
				Token pageToken = new Token(detail.getBusinessCode(), 86400);
				tokenService.save(pageToken);
				model.addAttribute("content", detail);
				model.addAttribute("pageToken", pageToken.getId());
				model.addAttribute("pageStep", 3);
			}
		} else {
			String appId = wr.getParameter(AccountConfig.AppIdParam);
			// 指定注册的app
			if (StringUtils.isEmpty(appId)) {
				appId = AccountConfig.ACCOUNT_CENTER;
			}
			model.addAttribute("appId", appId);
			Object pageStep = request.getSession().getAttribute("pageStep");
			model.addAttribute("pageStep", pageStep == null ? 1 : pageStep);
		}
		return new ModelAndView("changeAdmin/changeAdmin", model);
	}

	/**
	 * 通过businessCode查找详细信息
	 */
	@RequestMapping(value = "/detail/{businessCode}", method = RequestMethod.GET)
	@ResponseBody
	public ModelMap findDetail(@PathVariable("businessCode") String businessCode) {
		return success(changeAdminService.findByBusinessCode(businessCode));
	}

	/**
	 * 查找所有更换管理员申请的信息
	 * 
	 * @param pageNumber
	 * @param pageSize
	 * @return
	 */
	@RequestMapping(value = "/detail/list", method = RequestMethod.GET)
	@ResponseBody
	public Page<ChangeAdminDetail> findAll(Integer pageNumber, Integer pageSize, String name, String businessCode,
			String userName) {
		return changeAdminService.findAll(pageNumber, pageSize, name, businessCode, userName);
	}

	/**
	 * 审核通过
	 * 
	 * @param pageNumber
	 * @param pageSize
	 * @return
	 */
	@RequestMapping(value = "/detail/list", params = "status=ENABLED", method = RequestMethod.GET)
	@ResponseBody
	public Page<ChangeAdminDetail> findAllEnable(int pageNumber, int pageSize, String name, String businessCode,
			String userName) {
		return changeAdminService.findAllEnable(pageNumber, pageSize, name, businessCode, userName);
	}

	/**
	 * 待审核
	 * 
	 * @param pageNumber
	 * @param pageSize
	 * @return
	 */
	@RequestMapping(value = "/detail/list", params = "status=UNAUDIT", method = RequestMethod.GET)
	@ResponseBody
	public Page<ChangeAdminDetail> findAllUnAudit(int pageNumber, int pageSize, String name, String businessCode,
			String userName) {
		return changeAdminService.findAllUnAudit(pageNumber, pageSize, name, businessCode, userName);
	}

	/**
	 * 审核不通过信息列表
	 * 
	 * @param pageNumber
	 * @param pageSize
	 * @return
	 */
	@RequestMapping(value = "/detail/list", params = "status=UNAPPLY", method = RequestMethod.GET)
	@ResponseBody
	public Page<ChangeAdminDetail> findAllUnApply(int pageNumber, int pageSize, String name, String businessCode,
			String userName) {
		return changeAdminService.findAllUnApply(pageNumber, pageSize, name, businessCode, userName);
	}

	/**
	 * 审批通过
	 * 
	 * @param businessCode
	 * @return
	 */
	@RequestMapping(value = "/detail/audit", params = "enable=1")
	@ResponseBody
	public ModelMap enableDetail(String businessCode) {
		changeAdminService.enable(businessCode);
		ChangeAdminDetail detail = changeAdminService.findByBusinessCode(businessCode);
		// 邮件
		Setting mailTpl = settingService.findOne("templateForSendMailAfterApplyforChangeAdminSuccess");
		if (mailTpl != null && detail.getAdminEmail() != null) {
			ModelMap data = new ModelMap();
			data.put("content", detail);
			mailService.send(mailTpl.getValue(), detail.getAdminEmail(), data);
			return success();
		}
		return error("没有找到邮件模板，请设置后重新发送激活邮件");
	}

	/**
	 * 审批未通过
	 * 
	 * @param reason
	 * @param businessCode
	 * @return
	 */
	@RequestMapping(value = "/detail/audit", params = "enable=0")
	@ResponseBody
	public ModelMap disableDetail(String reason, String businessCode) {
		changeAdminService.disable(businessCode, reason);
		ChangeAdminDetail detail = changeAdminService.findByBusinessCode(businessCode);
		// 邮件
		Setting mailTpl = settingService.findOne("templateForSendMailAfterApplyforChangeAdminFailed");
		if (mailTpl != null && detail.getAdminEmail() != null) {
			ModelMap data = new ModelMap();
			data.put("reason", reason);
			data.put("content", detail);
			mailService.send(mailTpl.getValue(), detail.getAdminEmail(), data);
			return success();
		}
		return error("没有找到邮件模板，请设置后重新发送激活邮件");
	}

	/**
	 * 重新发送激活邮件
	 * 
	 * @param email
	 * @param businessCode
	 * @return
	 */
	@RequestMapping(value = "/detail/send")
	@ResponseBody
	public ModelMap sendEmail(String email, String businessCode) {
		ChangeAdminDetail detail = changeAdminService.findByBusinessCode(businessCode);
		// 邮件
		Setting mailTpl = settingService.findOne("templateForSendMailAfterRegisterSuccess");
		if (mailTpl != null && detail.getAdminEmail() != null) {
			// 3 days
			final Token token = new Token(detail.getBusinessCode(), 259200);

			tokenService.save(token);
			ModelMap data = new ModelMap();
			data.put("token", token.getId());
			data.put("content", detail);
			mailService.send(mailTpl.getValue(), email, data);
			return success();
		}
		return error("没有找到邮件模板，请设置后重新发送邮件");
	}

	/**
	 * 校验企业营业执照
	 * 
	 * @param businessCode
	 * @return
	 */
	@RequestMapping(value = "/changeadmin", params = "ch_businessCode", method = RequestMethod.GET)
	@ResponseBody
	public ModelMap validBusinessCode(String businessCode) {
		// 去掉可能存在的空格再进行检验
		businessCode = StringUtils.trimAllWhitespace(businessCode);
		if (!StringUtils.isEmpty(businessCode)) {
			ChangeAdminDetail detail = changeAdminService.findByBusinessCode(businessCode);
			if (null != detail) {
				if (detail.getAuditStatus().equals(Status.UNAUDIT.value())) {
					return error("企业资料正在审批，请勿重复申请");
				}
			}
		} else {
			return error("参数错误");
		}
		return success();
	}
}
