package com.cyksj.service.relation.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import com.cyksj.common.constant.Constant;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.common.util.IoKit;
import com.cyksj.common.util.J11HttpC;
import com.cyksj.common.util.Jsons;
import com.cyksj.common.util.StringUtil;
import com.cyksj.mapper.AccountMapper;
import com.cyksj.mapper.GroupsMapper;
import com.cyksj.mapper.GroupsRelationMapper;
import com.cyksj.mapper.UserMapper;
import com.cyksj.model.entity.Account;
import com.cyksj.model.entity.GroupsRelation;
import com.cyksj.model.entity.GroupsTrips;
import com.cyksj.model.entity.User;
import com.cyksj.model.request.NfDeviceReq;
import com.cyksj.redis.RedisService;
import com.cyksj.service.relation.GroupsRelationNetflixService;
import com.cyksj.service.user.UserBindRelationService;
import com.cyksj.task.JobManager;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 项目名: yhlxj2
 * 文件名: GroupsRelationNetflixServiceImpl
 * 创建者: JavaZou
 * 创建时间:2024/6/17 15:45
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class GroupsRelationNetflixServiceImpl implements GroupsRelationNetflixService {
	private final UserMapper userMapper;

	private final GroupsRelationMapper relationMapper;

	private final GroupsMapper groupsMapper;

	private final AccountMapper accountMapper;

	private final UserBindRelationService userBindRelationService;

	private final RedisService redisService;

	private final JobManager jobManager;

	@Override
	public JSONObject setNetflixSeatNum(Integer seatNum, String seatName, String account, String password, Date expiryTime, String code) {
		JSONObject params = new JSONObject();
		params.putOpt("username", account);
		params.putOpt("password", password);
		params.putOpt("seat_name", seatName);
		params.putOpt("seat_num", seatNum);
		params.putOpt("seat_time", expiryTime);
		if (StrUtil.isNotBlank(code)) {
			params.putOpt("pin_code", code);
		}
		//设置座位
		String url = Constant.ZHAOJU_MOVIES + "/netflix_seat_interface";
		log.info("设置账号:{} 奈飞用户:{}座位信息", account, seatName);
		try {
			HttpResponse<String> res =
					J11HttpC.custom()
							.ofPost()
							.url(url)
							.headers(J11HttpC.ReqType.raw_json)
							.body(HttpRequest.BodyPublishers.ofString(Jsons.toJson(params), IoKit.Charsets.UTF_8.getCharset()))
							.send(HttpResponse.BodyHandlers.ofString());
			String body = res.body();
			JSONObject jsonObject = Jsons.parseObject(body, JSONObject.class);
			JSONObject data = Jsons.parseObject(jsonObject.get("data"), JSONObject.class);
			Integer status = data.getInt("status");
			if (status == 2) {
				log.error("设置用户:{}奈飞座位号失败", seatName);
			}
			return data;
		} catch (Exception e) {
			log.error("设置用户:{}奈飞座位号错误,msg:{}", seatName, StringUtil.getErrorText(e));
		}
		JSONObject jsonObject = new JSONObject();
		jsonObject.putOpt("status", 2);
		return jsonObject;
	}

	@Override
	public JSONObject setNetflixPin(Long relationId, long userId, String code) {
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		GroupsRelation relation = relationMapper.selectById(relationId);
		if (!userIdList.contains(relation.getUserId())) {
			throw BusinessRuntimeException.getInstance("您车票已失效");
		}
		GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
		Account account = accountMapper.selectById(groupsTrips.getAccountId());
		if (account.getGoodsId() != 1) {
			throw BusinessRuntimeException.getInstance("系统错误");
		}
		User user = userMapper.selectById(relation.getUserId());
		if (!redisService.setNx(RedisService.key.NF_SET_TIME_LIMIT.getName() + relationId, relationId, RedisService.key.NF_SET_TIME_LIMIT.getTimeout())) {
			throw BusinessRuntimeException.getInstance("一分钟内可执行一次");
		}
		JSONObject jsonObject = setNetflixSeatNum(relation.getNum(), user.getNickname(), account.getAccount(), account.getPassword(), relation.getExpiryTime(), code);
		relation.setPinCode(code);
		relationMapper.updateById(relation);
		return jsonObject;
	}

	@Override
	public Integer getPinStatus(String taskId) throws Exception {
		JSONObject params = new JSONObject();
		params.putOpt("transId", taskId);
		//查询任务状态
		String url = Constant.ZHAOJU_MOVIES + "/netflix_task_status";
		HttpResponse<String> res =
				J11HttpC.custom()
						.ofPost()
						.url(url)
						.headers(J11HttpC.ReqType.raw_json)
						.body(HttpRequest.BodyPublishers.ofString(Jsons.toJson(params), IoKit.Charsets.UTF_8.getCharset()))
						.send(HttpResponse.BodyHandlers.ofString());
		String body = res.body();
		JSONObject jsonObject = Jsons.parseObject(body, JSONObject.class);
		JSONObject data = Jsons.parseObject(jsonObject.get("data"), JSONObject.class);
		Integer status = data.getInt("status");
		return status;
	}

	@Override
	public Boolean confirmUpdate(String nfUrl) {
		String key = RedisService.key.NETFLIX_UPDATE_LIMIT_TIME.getName();
		if (!redisService.setNx(key, 1L, 30L)) {
			throw BusinessRuntimeException.getInstance("系统繁忙，请稍后点击..");
		}
		JSONObject params = new JSONObject();
		params.putOpt("url", nfUrl);
		//确认更新点击
		String url = Constant.ZHAOJU_MOVIES + "/netflix_primary_action";
		try {
			cn.hutool.http.HttpResponse execute = HttpUtil
					.createPost(url)
					.body(params.toString(), "application/json")
					.setConnectionTimeout(30000)
					.setReadTimeout(30000)
					.execute();
			JSONObject resp = Jsons.parseObject(execute.body(), JSONObject.class);
			redisService.del(key);
			return resp.getBool("success");
		} catch (Exception e) {
		}
		return false;
	}

	/**
	 * 定时设置座位号
	 * 30s执行一次
	 */
	@Override
	public void timingSetNetflix(Integer num, String nickname, String account, String password, Date expiryTime, AtomicInteger start) {
		try {
			String key = RedisService.key.NETFLIX_SET_LIMIT_TIME.getName();
			if (!redisService.setNx(key, 1L, 30L)) {
				jobManager.addJob(30001, () -> {
					if (start.get() > 3) {
						return;
					}
					start.incrementAndGet();
					timingSetNetflix(num, nickname, account, password, expiryTime, start);
				});
			} else {
				setNetflixSeatNum(num, nickname, account, password, expiryTime, null);
				log.info("当前时间：{}开始调用设置奈飞座位信息接口", DateTime.now());
			}
		} catch (Exception e) {
		}
	}

	@Override
	public JSONObject nfKickOut(long userId, Long relationId) {
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		GroupsRelation relation = relationMapper.selectById(relationId);
		if (!userIdList.contains(relation.getUserId())) {
			throw BusinessRuntimeException.getInstance("您车票已失效");
		}
		GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
		Account account = accountMapper.selectById(groupsTrips.getAccountId());
		if (account.getGoodsId() != 1) {
			throw BusinessRuntimeException.getInstance("系统错误");
		}
		User user = userMapper.selectById(relation.getUserId());
		if (!redisService.setNx(RedisService.key.NF_KICKOUT_TIME_LIMIT.getName()  + relationId, relationId, RedisService.key.NF_KICKOUT_TIME_LIMIT.getTimeout())) {
			throw BusinessRuntimeException.getInstance("一分钟内可执行一次");
		}
		return doNfKickOut(relation.getNum(), user.getNickname(), account.getAccount(), account.getPassword(),account.getCookie(), relation.getExpiryTime(), relation.getPinCode());
	}

	@Override
	public void clickNfHouseholdDevice(NfDeviceReq nfDeviceReq) {
		String url = nfDeviceReq.getUrl();
		if (!confirmUpdate(url)) {
			throw BusinessRuntimeException.getInstance("程序代点失败");
		}
	}

	/**
	 * 踢出奈飞设备
	 */
	private JSONObject doNfKickOut(Integer seatNum, String seatName, String account, String password, String cookie, Date expiryTime, String code) {
		JSONObject params = new JSONObject();
		params.putOpt("username", account);
		params.putOpt("password", password);
		params.putOpt("seat_name", seatName);
		params.putOpt("seat_num", seatNum);
		params.putOpt("seat_time", expiryTime);
		if (StrUtil.isNotBlank(code)) {
			params.putOpt("pin_code", code);
		}
		if (StrUtil.isNotEmpty(cookie)) {
			params.putOpt("cookie", cookie);
		}
		//设置座位
		String url = Constant.ZHAOJU_MOVIES + "/netflix_seat_interface";
		log.info("设置账号:{} 奈飞用户:{}座位信息", account, seatName);
		try {
			HttpResponse<String> res =
					J11HttpC.custom()
							.ofPost()
							.url(url)
							.headers(J11HttpC.ReqType.raw_json)
							.body(HttpRequest.BodyPublishers.ofString(Jsons.toJson(params), IoKit.Charsets.UTF_8.getCharset()))
							.send(HttpResponse.BodyHandlers.ofString());
			String body = res.body();
			JSONObject jsonObject = Jsons.parseObject(body, JSONObject.class);
			JSONObject data = Jsons.parseObject(jsonObject.get("data"), JSONObject.class);
			Integer status = data.getInt("status");
			if (status == 2) {
				log.error("设置用户:{}奈飞座位号失败", seatName);
			}
			return data;
		} catch (Exception e) {
			log.error("设置用户:{}奈飞座位号错误,msg:{}", seatName, StringUtil.getErrorText(e));
		}
		JSONObject jsonObject = new JSONObject();
		jsonObject.putOpt("status", 2);
		return jsonObject;
	}
}
