package jj.tech.paolu.biz.webadmin.component;

import java.net.URI;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.microsoft.playwright.APIRequestContext;
import com.microsoft.playwright.APIResponse;
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.BrowserType;
import com.microsoft.playwright.FrameLocator;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
import com.microsoft.playwright.Response;
import com.microsoft.playwright.options.RequestOptions;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import jj.tech.paolu.biz.webadmin.service.G24Service;
import jj.tech.paolu.biz.webadmin.service.Idc9998Sevice;
import jj.tech.paolu.config.enums.Games;
import jj.tech.paolu.repository.mybatis.dao.Idc9998AdminInfoMapper;
import jj.tech.paolu.repository.mybatis.entity.Idc9998AdminInfo;
import jj.tech.paolu.utils.YMHttp;
@Component
public class Hgt8Component{
	private static Logger logger = LoggerFactory.getLogger(Hgt8Component.class);
	
	public static Playwright playwright;
	public static Browser browser;
	public static HashMap<String, Hgt8Component> instances = new HashMap<String, Hgt8Component>();
	public static Boolean headless;
	public static Long defaultTimeout = 10000L;
	
	public BrowserContext browserContext;
	public APIRequestContext aPIRequestContext;
	public Page page;
	public Idc9998AdminInfo admin;
	public AtomicInteger wrong_times = new AtomicInteger(0);
	
	
	@Autowired Idc9998Sevice idc9998Sevice;
	@Autowired Idc9998AdminInfoMapper idc9998AdminInfoMapper;
	@Autowired G24Service g24Service;
	
	@Value("${idc9998.headless}")
    public void setHeadless(Boolean headless){
		Hgt8Component.headless= headless;
    }
	
	
	public Hgt8Component() {
	}
	

	
	
	@PostConstruct
	public void run() throws Exception {
		playwright = Playwright.create();
		playwright.selectors().setTestIdAttribute("id");
		//设置有是否UI, 每个操作减慢执行200毫秒
		browser = playwright.chromium().launch(
	    		new BrowserType.LaunchOptions()
	    		.setHeadless(headless)
	    		.setSlowMo(200)
	    );
		
//		Idc9998AdminInfo admin =  idc9998Sevice.getByUserName("bk7897");
//		this.addInstance(admin.getUser_name());
		
		logger.info("playwright started");
	}
	
	
    @PreDestroy
    public void onDestroy() throws Exception {
    	browser.close();
		playwright.close();
    	logger.info("playwright is close");
    }
    
    
    public Hgt8Component addInstance(String userName) {
    	Idc9998AdminInfo bean = idc9998Sevice.getByUserName(userName);
    	if(bean==null) {
    		return null;
    	}
    	Hgt8Component instance = Hgt8Component.instances.get(userName);
		if(instance == null) {
			Hgt8Component inst = new Hgt8Component();
			inst.browserContext = browser.newContext(
					new Browser.NewContextOptions().setStorageState(bean.getLogin_info())
			);
			inst.browserContext.setDefaultNavigationTimeout(defaultTimeout);
			inst.aPIRequestContext = inst.browserContext.request();
			inst.page = inst.browserContext.newPage();
			inst.page.setDefaultTimeout(defaultTimeout);
			inst.admin = bean;
			inst.idc9998Sevice = this.idc9998Sevice;
			inst.idc9998AdminInfoMapper = this.idc9998AdminInfoMapper;
			inst.g24Service = this.g24Service;
			Hgt8Component.instances.put(userName, inst);
			return inst;
		}else {
			return instance;
		}
	}
    
	public Hgt8Component getInstance(String userName) {
		return instances.get(userName);
	}
	
	public void deleteInstance(String userName) {
		instances.get(userName).close();
		instances.remove(userName);
	}
	
	public void updateInstance(String userName) {
		if(instances.get(userName) != null) {
			instances.get(userName).close();
			instances.remove(userName);
			instances.put(userName, new Hgt8Component());
		}
	}
	
	public void close() {
		if(this.page != null) {
			this.page.close();
		}
		if(this.browserContext != null) {
			this.browserContext.close();
		}
		
	}
	
	
	public Boolean login() {
		if(this.admin.getIs_online() != 1) {
			return this.forceLogin();
		}else {
			return true;
		}
	}
	
	public Boolean forceLogin() {
		try {
			this.page.navigate(this.admin.getDomain()+ "/search.aspx");
			FrameLocator ifr_main = this.page.frameLocator("#ifr_main");
			
			//管理员账号
			ifr_main.getByTestId("lineCode")
				.fill(this.admin.getManager_name());
			ifr_main.locator("xpath=//input[@class='btn']")
			.click();
			
			//login
			Response response = this.page.waitForResponse("**/captcha_image/2*", 
				() -> {
			});
			byte[] image_bytes = response.body();
			JsonNode root = 
			YMHttp.customApi(Base64.encodeBase64String(image_bytes));
			JsonNode code_num = root.get("data").get("data");
			ifr_main.getByTestId("userName").fill(this.admin.getUser_name());
			this.page.waitForTimeout(1_500);
			ifr_main.getByTestId("password").fill(this.admin.getUser_password());
			ifr_main.getByTestId("code").fill(code_num.asText());
			this.page.waitForTimeout(5_500);	//wait 2500
			ifr_main.getByTestId("btnSubmit").click();
			
			
			//同意
			this.page.waitForTimeout(1_500);	//wait 2500
			this.page.frameLocator("#ifr_main")
			.locator("xpath=//input[@class='protocol-btn-y']")
			.click();
			
			//关闭弹窗
			ifr_main.getByTestId("tc_Close")
			.click();
			
			
			//及时注单
			this.page.frameLocator("#ifr_main")
			.locator("#jishi-order")
			.click();
			
			
			//this.G_24_Curr().join();
			
			
			//更新用户登录状态
//			String loginInfo = this.aPIRequestContext.storageState();
//			idc9998Sevice.updateLoginInfo(this.admin.getUser_name(), loginInfo, 1);
//			this.admin.setIs_online(1);
//			this.admin.setLogin_info(loginInfo);
			
			
			return true;
			
		}catch (Exception e) {
			logger.error(e.getMessage());
			return false;
		}
		
	}
	
	public CompletableFuture<Response> G_24_Curr() {
		CompletableFuture<Response> future = CompletableFuture.supplyAsync(() -> {
			Response response = this.page.waitForResponse(resp -> 
				{
					//System.err.println(resp.url());
					String g24curr_url = this.admin.getDomain()+"/wb2/jd001/m018";
					if(resp.status() == 200 && g24curr_url.equals(resp.url())) {
						return true;
					}else {
						return false;
					}
			    }, 
			    () -> {
			      //System.out.println("所有返回响应");
			    }
	        );
			g24Service.getCurretG24Data(response.text());
			
	    	return response;
	    });
		

		return future.handleAsync((Response re, Throwable ex) -> {
	        if(ex != null) {
	        	logger.error(ex.getMessage());
	        	this.wrong_times.getAndIncrement();
	        	if(this.wrong_times.get()>3) {
	        		return  CompletableFuture.completedFuture(re);
	        	}
	            return G_24_Curr();
	        } else {
	        	this.wrong_times = new AtomicInteger(0);
	            return G_24_Curr();
	        }
			
	    })
		.thenCompose(Function.identity());
		
		
	}
	
	
	public void G_24_His(Integer page, String issuet, LocalDate localDate) {
		try {
			if(this.admin.getIs_online()==1) {
				HashMap<String, String> pram = new HashMap<String, String>();
				pram.put("gameID", Games.G_24.getCode());
				pram.put("currtentPage",page.toString());
				pram.put("asDate",localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
				pram.put("issuet", "");
				
				RequestOptions  requestOptions  =
				RequestOptions.create().setHeader("Content-Type", "application/json")
		        .setData(pram);
				
				APIResponse s001s =
				this.aPIRequestContext.post(this.admin.getDomain()+"/wb2/jg0001/s001s", requestOptions);
				
				String storageState = aPIRequestContext.storageState();
				System.out.println(storageState);
				System.err.println(s001s.text());
				
			}
		}catch (Exception e) {
			logger.error(e.getMessage());
		}
		
	}

	

}
