// services/gitea-oauth.js
const database = require('../config/database');

class GiteaOAuthService {
  constructor() {
    this.clientId = process.env.GITEA_CLIENT_ID;
    this.clientSecret = process.env.GITEA_CLIENT_SECRET;
    this.baseUrl = (process.env.GITEA_BASE_URL || 'https://gitea.com').replace(/\/$/, '');
    this.redirectUri = process.env.GITEA_REDIRECT_URI || 'http://localhost:8012/api/vcs/gitea/auth/callback';
  }

  getAuthUrl(state) {
    if (!this.clientId) throw new Error('Gitea OAuth not configured');
    const authUrl = `${this.baseUrl}/login/oauth/authorize`;
    const params = new URLSearchParams({
      client_id: this.clientId,
      redirect_uri: this.redirectUri,
      response_type: 'code',
      // Request both user and repository read scopes
      scope: 'read:user read:repository',
      state
    });
    return `${authUrl}?${params.toString()}`;
  }

  async exchangeCodeForToken(code) {
    const tokenUrl = `${this.baseUrl}/login/oauth/access_token`;
    const resp = await fetch(tokenUrl, {
      method: 'POST',
      headers: { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' },
      body: new URLSearchParams({
        client_id: this.clientId,
        client_secret: this.clientSecret,
        code,
        grant_type: 'authorization_code',
        redirect_uri: this.redirectUri
      })
    });
    let data = null;
    try { data = await resp.json(); } catch (_) { data = null; }
    if (!resp.ok || data?.error) {
      const detail = data?.error_description || data?.error || (await resp.text().catch(() => '')) || 'unknown_error';
      throw new Error(`Gitea token exchange failed: ${detail}`);
    }
    return data.access_token;
  }

  async getUserInfo(accessToken) {
    const resp = await fetch(`${this.baseUrl}/api/v1/user`, { headers: { Authorization: `Bearer ${accessToken}` } });
    if (!resp.ok) {
      let txt = '';
      try { txt = await resp.text(); } catch (_) {}
      throw new Error(`Failed to fetch Gitea user (status ${resp.status}): ${txt}`);
    }
    return await resp.json();
  }

  async storeToken(accessToken, user) {
    const result = await database.query(
      `INSERT INTO gitea_user_tokens (access_token, gitea_username, gitea_user_id, scopes, expires_at)
       VALUES ($1, $2, $3, $4, $5)
       ON CONFLICT (id) DO UPDATE SET access_token = EXCLUDED.access_token, gitea_username = EXCLUDED.gitea_username, gitea_user_id = EXCLUDED.gitea_user_id, scopes = EXCLUDED.scopes, expires_at = EXCLUDED.expires_at, updated_at = NOW()
       RETURNING *`,
      [accessToken, user.login, user.id, JSON.stringify(['read:repository']), null]
    );
    return result.rows[0];
  }

  async getToken() {
    const r = await database.query('SELECT * FROM gitea_user_tokens ORDER BY created_at DESC LIMIT 1');
    return r.rows[0];
  }
}

module.exports = GiteaOAuthService;


