'use strict';

const crypto = require('crypto');
const fetch = require('node-fetch');
const { URLSearchParams } = require('url');

// ─── 常量 ───
const OWNER_EMAIL = (process.env.ZY_OWNER_EMAIL || '565183519@qq.com').trim().toLowerCase();
const GITHUB_CLIENT_ID = process.env.GITHUB_CLIENT_ID;
const GITHUB_CLIENT_SECRET = process.env.GITHUB_CLIENT_SECRET;
const GITHUB_REDIRECT_URI = process.env.GITHUB_REDIRECT_URI || 'http://localhost:3800/api/oauth/github/callback';
const NOTION_CLIENT_ID = process.env.NOTION_CLIENT_ID;
const NOTION_CLIENT_SECRET = process.env.NOTION_CLIENT_SECRET;
const NOTION_REDIRECT_URI = process.env.NOTION_REDIRECT_URI || 'http://localhost:3800/api/oauth/notion/callback';
const STATE_SECRET = process.env.OAUTH_STATE_SECRET || 'default-secret-change-me';

// ─── 状态令牌生成 ───
function generateStateToken(email) {
  const hash = crypto.createHmac('sha256', STATE_SECRET)
    .update(email)
    .digest('hex');
  return `${hash}:${Date.now()}`;
}

function verifyStateToken(token, email) {
  const [hash, timestamp] = token.split(':');
  if (!hash || !timestamp) return false;
  
  // 状态令牌10分钟过期
  if (Date.now() - Number(timestamp) > 10 * 60 * 1000) return false;
  
  const expectedHash = crypto.createHmac('sha256', STATE_SECRET)
    .update(email)
    .digest('hex');
  
  return hash === expectedHash;
}

// ─── GitHub OAuth ───
async function getGitHubOAuthUrl(email) {
  if (email.toLowerCase() !== OWNER_EMAIL) {
    throw new Error('仅限主权者邮箱使用');
  }
  
  const state = generateStateToken(email);
  const params = new URLSearchParams({
    client_id: GITHUB_CLIENT_ID,
    redirect_uri: GITHUB_REDIRECT_URI,
    scope: 'user:email',
    state
  });
  
  return `https://github.com/login/oauth/authorize?${params.toString()}`;
}

async function handleGitHubCallback(code, state) {
  if (!verifyStateToken(state, OWNER_EMAIL)) {
    throw new Error('无效的状态令牌');
  }
  
  // 交换access token
  const tokenParams = new URLSearchParams({
    client_id: GITHUB_CLIENT_ID,
    client_secret: GITHUB_CLIENT_SECRET,
    code,
    redirect_uri: GITHUB_REDIRECT_URI
  });
  
  const tokenRes = await fetch('https://github.com/login/oauth/access_token', {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: tokenParams
  });
  
  const tokenData = await tokenRes.json();
  if (tokenData.error) {
    throw new Error(`GitHub OAuth错误: ${tokenData.error_description || tokenData.error}`);
  }
  
  // 返回与验证码登录相同的session token结构
  return {
    token: crypto.randomBytes(32).toString('hex'),
    expiresAt: Date.now() + 7 * 24 * 60 * 60 * 1000, // 7天
    provider: 'github',
    email: OWNER_EMAIL
  };
}

// ─── Notion OAuth ───
async function getNotionOAuthUrl(email) {
  if (email.toLowerCase() !== OWNER_EMAIL) {
    throw new Error('仅限主权者邮箱使用');
  }
  
  const state = generateStateToken(email);
  const params = new URLSearchParams({
    client_id: NOTION_CLIENT_ID,
    redirect_uri: NOTION_REDIRECT_URI,
    response_type: 'code',
    owner: 'user',
    state
  });
  
  return `https://api.notion.com/v1/oauth/authorize?${params.toString()}`;
}

async function handleNotionCallback(code, state) {
  if (!verifyStateToken(state, OWNER_EMAIL)) {
    throw new Error('无效的状态令牌');
  }
  
  // 交换access token
  const tokenRes = await fetch('https://api.notion.com/v1/oauth/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Basic ${Buffer.from(`${NOTION_CLIENT_ID}:${NOTION_CLIENT_SECRET}`).toString('base64')}`
    },
    body: JSON.stringify({
      grant_type: 'authorization_code',
      code,
      redirect_uri: NOTION_REDIRECT_URI
    })
  });
  
  const tokenData = await tokenRes.json();
  if (tokenData.error) {
    throw new Error(`Notion OAuth错误: ${tokenData.error_description || tokenData.error}`);
  }
  
  // 返回与验证码登录相同的session token结构
  return {
    token: crypto.randomBytes(32).toString('hex'),
    expiresAt: Date.now() + 7 * 24 * 60 * 60 * 1000, // 7天
    provider: 'notion',
    email: OWNER_EMAIL
  };
}

module.exports = {
  getGitHubOAuthUrl,
  handleGitHubCallback,
  getNotionOAuthUrl,
  handleNotionCallback
};