import type { EventDetail, Player } from "../types";
import * as cheerio from "cheerio";
import { XCXAPI } from "../services/xcxApi";
import { KAIQIU_BASE_URL, LOGTO_DOMAIN } from "./common";
import { RedisClient } from "bun";
import { createRemoteJWKSet, jwtVerify } from 'jose';
import { LOGTO_RESOURCE } from "./constants";

const REQUIRED_ENVS = [
  process.env.KAIQIUCC_TOKEN,
  process.env.REDIS,
];

if (!REQUIRED_ENVS.every(v => !!v)) {
  console.error('Missing required environment variables. Please check your .env');
  process.exit(1);
}

export const REDIS_CACHE_HOUR = Number(process.env.REDIS_CACHE_HOUR) || 8;

console.debug('Cache hour: %s', REDIS_CACHE_HOUR);

export const xcxApi = new XCXAPI(process.env.KAIQIUCC_TOKEN ?? '');

export const redis = new RedisClient(process.env.REDIS ?? '');

export const htmlRequestHeaders = {
  "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
  "accept-language": "zh-CN,zh;q=0.8",
  "cache-control": "max-age=0",
  "priority": "u=0, i",
  "sec-ch-ua": "\"Not(A:Brand\";v=\"8\", \"Chromium\";v=\"144\", \"Brave\";v=\"144\"",
  "sec-ch-ua-mobile": "?0",
  "sec-ch-ua-platform": "\"Windows\"",
  "sec-fetch-dest": "document",
  "sec-fetch-mode": "navigate",
  "sec-fetch-site": "none",
  "sec-fetch-user": "?1",
  "sec-gpc": "1",
  "upgrade-insecure-requests": "1",
  "cookie": "SECKEY_ABVK=oTGgqH4ypGPFVdQ3J9K7PoAOPdZ+8R7CsUzi75gelcg%3D; uchome_sendmail=1"
}


/**
 * 
 * @param matchId 比赛 ID
 * @returns HTML
 */
export async function fetchEventContentHTML(matchId: string) {
  const url = `${KAIQIU_BASE_URL}/home/space.php?do=event&id=${matchId}&view=member&status=2`;
  const resp = await fetch(url, { headers: htmlRequestHeaders });
  return resp.text() ?? ''
}

export function parseEventInfo(html: string, eventId: string): EventDetail {
  const $ = cheerio.load(html);
  const title = $('h2.title a').text();
  const itemHref = $('.sub_menu a.active').attr('href') ?? '';
  const itemId = /\S+item_id=(\d+)$/.exec(itemHref)?.[1] ?? '';
  const players: Player[] = [];
  const playersEl = $('.thumb');
  for (const player of playersEl) {
    const img = $(player).find('.image img').attr('src') ?? '';
    const name = $(player).find('h6').text().trim();
    const uid = /space-(?<uid>\d+).html/.exec($(player).find('h6 a').attr('href') ?? '')?.groups?.uid ?? '';
    const info = $(player).find('p:nth-of-type(2)').text().replace(/\s/g, '');
    const score = /^.*?\b(\d+)\b/.exec(info)?.[1] ?? '';
    players.push({ name, avatar: img, score, info, uid });
  }
  return {
    itemId,
    eventId,
    title,
    players,
  }
}

export const extractBearerTokenFromHeaders = (authorization: string | null) => {
  if (!authorization) {
    return null;
  }

  if (!authorization.startsWith('Bearer')) {
    return authorization;
  }

  return authorization.slice(7); // The length of 'Bearer ' is 7
};

const jwks = createRemoteJWKSet(new URL(`${LOGTO_DOMAIN}/oidc/jwks`));

export const verifyLogtoToken = async (headers: Headers | string) => {
  const auth = typeof headers === 'string' ? headers : headers.get('Authorization');
  const token = extractBearerTokenFromHeaders(auth);
  // console.debug('Authorization', { auth, token });
  if (!token) return {};
  const { payload } = await jwtVerify(
    // The raw Bearer Token extracted from the request header
    token,
    jwks,
    {
      // Expected issuer of the token, issued by the Logto server
      issuer: `${LOGTO_DOMAIN}/oidc`,
      // Expected audience token, the resource indicator of the current API
      audience: LOGTO_RESOURCE,
    }
  );
  // console.debug('Payload', payload);
  // Sub is the user ID, used for user identification
  return payload
}
