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

class GitLabOAuthService {
  constructor() {
    this.clientId = process.env.GITLAB_CLIENT_ID;
    this.clientSecret = process.env.GITLAB_CLIENT_SECRET;
    this.baseUrl = (process.env.GITLAB_BASE_URL || 'https://gitlab.com').replace(/\/$/, '');
    this.redirectUri = process.env.GITLAB_REDIRECT_URI || 'http://localhost:8012/api/vcs/gitlab/auth/callback';
  }

  getAuthUrl(state) {
    if (!this.clientId) throw new Error('GitLab OAuth not configured');
    const authUrl = `${this.baseUrl}/oauth/authorize`;
    const params = new URLSearchParams({
      client_id: this.clientId,
      redirect_uri: this.redirectUri,
      response_type: 'code',
      scope: 'read_api api read_user',
      state
    });
    return `${authUrl}?${params.toString()}`;
  }

  async exchangeCodeForToken(code) {
    const tokenUrl = `${this.baseUrl}/oauth/token`;
    const resp = await fetch(tokenUrl, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        client_id: this.clientId,
        client_secret: this.clientSecret,
        code,
        grant_type: 'authorization_code',
        redirect_uri: this.redirectUri
      })
    });
    const data = await resp.json();
    if (!resp.ok || data.error) throw new Error(data.error_description || 'GitLab token exchange failed');
    return data.access_token;
  }

  async getUserInfo(accessToken) {
    const resp = await fetch(`${this.baseUrl}/api/v4/user`, {
      headers: { Authorization: `Bearer ${accessToken}` }
    });
    if (!resp.ok) throw new Error('Failed to fetch GitLab user');
    return await resp.json();
  }

  async storeToken(accessToken, user) {
    const result = await database.query(
      `INSERT INTO gitlab_user_tokens (access_token, gitlab_username, gitlab_user_id, scopes, expires_at)
       VALUES ($1, $2, $3, $4, $5)
       ON CONFLICT (id) DO UPDATE SET access_token = EXCLUDED.access_token, gitlab_username = EXCLUDED.gitlab_username, gitlab_user_id = EXCLUDED.gitlab_user_id, scopes = EXCLUDED.scopes, expires_at = EXCLUDED.expires_at, updated_at = NOW()
       RETURNING *`,
      [accessToken, user.username, user.id, JSON.stringify(['read_api','api','read_user']), null]
    );
    return result.rows[0];
  }

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

module.exports = GitLabOAuthService;


