/**
 * TASKMATE - Gitea Service
 * =========================
 * Integration mit Gitea API
 */

const logger = require('../utils/logger');

const GITEA_URL = process.env.GITEA_URL || 'https://gitea-undso.aegis-sight.de';
const GITEA_TOKEN = process.env.GITEA_TOKEN;
const GITEA_ORG = process.env.GITEA_ORG || 'AegisSight'; // Standard-Organisation für neue Repos

/**
 * Basis-Fetch für Gitea API
 */
async function giteaFetch(endpoint, options = {}) {
  if (!GITEA_TOKEN) {
    throw new Error('Gitea-Token nicht konfiguriert');
  }

  const url = `${GITEA_URL}/api/v1${endpoint}`;

  const response = await fetch(url, {
    ...options,
    headers: {
      'Authorization': `token ${GITEA_TOKEN}`,
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      ...options.headers
    }
  });

  if (!response.ok) {
    const errorText = await response.text();
    logger.error(`Gitea API Fehler: ${response.status} - ${errorText}`);
    throw new Error(`Gitea API Fehler: ${response.status}`);
  }

  return response.json();
}

/**
 * Alle Repositories der Organisation abrufen
 */
async function listRepositories(options = {}) {
  try {
    const page = options.page || 1;
    const limit = options.limit || 50;

    // Repositories der Organisation abrufen
    const repos = await giteaFetch(`/orgs/${GITEA_ORG}/repos?page=${page}&limit=${limit}`);

    return {
      success: true,
      repositories: repos.map(repo => ({
        id: repo.id,
        name: repo.name,
        fullName: repo.full_name,
        owner: repo.owner.login,
        description: repo.description || '',
        cloneUrl: repo.clone_url,
        htmlUrl: repo.html_url,
        defaultBranch: repo.default_branch,
        private: repo.private,
        fork: repo.fork,
        stars: repo.stars_count,
        forks: repo.forks_count,
        updatedAt: repo.updated_at,
        createdAt: repo.created_at
      }))
    };
  } catch (error) {
    logger.error('Fehler beim Abrufen der Repositories:', error);
    return { success: false, error: error.message };
  }
}

/**
 * Repository-Details abrufen
 */
async function getRepository(owner, repo) {
  try {
    const repoData = await giteaFetch(`/repos/${owner}/${repo}`);

    return {
      success: true,
      repository: {
        id: repoData.id,
        name: repoData.name,
        fullName: repoData.full_name,
        owner: repoData.owner.login,
        description: repoData.description || '',
        cloneUrl: repoData.clone_url,
        htmlUrl: repoData.html_url,
        defaultBranch: repoData.default_branch,
        private: repoData.private,
        fork: repoData.fork,
        stars: repoData.stars_count,
        forks: repoData.forks_count,
        size: repoData.size,
        updatedAt: repoData.updated_at,
        createdAt: repoData.created_at
      }
    };
  } catch (error) {
    logger.error(`Fehler beim Abrufen des Repositories ${owner}/${repo}:`, error);
    return { success: false, error: error.message };
  }
}

/**
 * Branches eines Repositories abrufen
 */
async function getRepositoryBranches(owner, repo) {
  try {
    const branches = await giteaFetch(`/repos/${owner}/${repo}/branches`);

    return {
      success: true,
      branches: branches.map(branch => ({
        name: branch.name,
        commit: branch.commit?.id,
        protected: branch.protected
      }))
    };
  } catch (error) {
    logger.error(`Fehler beim Abrufen der Branches für ${owner}/${repo}:`, error);
    return { success: false, error: error.message };
  }
}

/**
 * Commits eines Repositories abrufen
 */
async function getRepositoryCommits(owner, repo, options = {}) {
  try {
    const page = options.page || 1;
    const limit = options.limit || 20;
    const branch = options.branch || '';

    let endpoint = `/repos/${owner}/${repo}/commits?page=${page}&limit=${limit}`;
    if (branch) {
      endpoint += `&sha=${branch}`;
    }

    const commits = await giteaFetch(endpoint);

    return {
      success: true,
      commits: commits.map(commit => ({
        sha: commit.sha,
        shortSha: commit.sha.substring(0, 7),
        message: commit.commit.message,
        author: commit.commit.author.name,
        email: commit.commit.author.email,
        date: commit.commit.author.date,
        htmlUrl: commit.html_url
      }))
    };
  } catch (error) {
    logger.error(`Fehler beim Abrufen der Commits für ${owner}/${repo}:`, error);
    return { success: false, error: error.message };
  }
}

/**
 * Neues Repository in der Organisation erstellen
 */
async function createRepository(name, options = {}) {
  try {
    // Repository unter der Organisation erstellen
    const repoData = await giteaFetch(`/orgs/${GITEA_ORG}/repos`, {
      method: 'POST',
      body: JSON.stringify({
        name,
        description: options.description || '',
        private: options.private !== false,
        auto_init: options.autoInit !== false,
        default_branch: options.defaultBranch || 'main',
        readme: options.readme || 'Default'
      })
    });

    logger.info(`Repository in Organisation ${GITEA_ORG} erstellt: ${repoData.full_name}`);

    return {
      success: true,
      repository: {
        id: repoData.id,
        name: repoData.name,
        fullName: repoData.full_name,
        owner: repoData.owner.login,
        cloneUrl: repoData.clone_url,
        htmlUrl: repoData.html_url,
        defaultBranch: repoData.default_branch
      }
    };
  } catch (error) {
    logger.error('Fehler beim Erstellen des Repositories:', error);
    return { success: false, error: error.message };
  }
}

/**
 * Repository löschen
 */
async function deleteRepository(owner, repo) {
  try {
    await giteaFetch(`/repos/${owner}/${repo}`, {
      method: 'DELETE'
    });

    logger.info(`Repository gelöscht: ${owner}/${repo}`);
    return { success: true };
  } catch (error) {
    logger.error(`Fehler beim Löschen des Repositories ${owner}/${repo}:`, error);
    return { success: false, error: error.message };
  }
}

/**
 * Authentifizierten Benutzer abrufen
 */
async function getCurrentUser() {
  try {
    const user = await giteaFetch('/user');

    return {
      success: true,
      user: {
        id: user.id,
        login: user.login,
        fullName: user.full_name,
        email: user.email,
        avatarUrl: user.avatar_url
      }
    };
  } catch (error) {
    logger.error('Fehler beim Abrufen des aktuellen Benutzers:', error);
    return { success: false, error: error.message };
  }
}

/**
 * Prüft ob die Gitea-Verbindung funktioniert
 */
async function testConnection() {
  try {
    const result = await getCurrentUser();
    return {
      success: result.success,
      connected: result.success,
      user: result.user,
      giteaUrl: GITEA_URL,
      organization: GITEA_ORG
    };
  } catch (error) {
    return {
      success: false,
      connected: false,
      error: error.message,
      giteaUrl: GITEA_URL,
      organization: GITEA_ORG
    };
  }
}

/**
 * Clone-URL mit Token für private Repos
 */
function getAuthenticatedCloneUrl(cloneUrl) {
  if (!GITEA_TOKEN) {
    return cloneUrl;
  }
  // Füge Token zur URL hinzu
  return cloneUrl.replace('https://', `https://${GITEA_TOKEN}@`);
}

/**
 * Gitea-URL ohne Token (für Anzeige)
 */
function getSafeCloneUrl(cloneUrl) {
  // Entferne Token aus URL falls vorhanden
  return cloneUrl.replace(/https:\/\/[^@]+@/, 'https://');
}

/**
 * Repository-Einstellungen aktualisieren (z.B. default_branch ändern)
 */
async function updateRepository(owner, repo, options = {}) {
  try {
    const updateData = {};
    if (options.defaultBranch) updateData.default_branch = options.defaultBranch;
    if (options.description !== undefined) updateData.description = options.description;
    if (options.private !== undefined) updateData.private = options.private;

    const repoData = await giteaFetch(`/repos/${owner}/${repo}`, {
      method: 'PATCH',
      body: JSON.stringify(updateData)
    });

    logger.info(`Repository ${owner}/${repo} aktualisiert (default_branch: ${repoData.default_branch})`);
    return {
      success: true,
      repository: {
        id: repoData.id,
        name: repoData.name,
        fullName: repoData.full_name,
        defaultBranch: repoData.default_branch
      }
    };
  } catch (error) {
    logger.error(`Fehler beim Aktualisieren des Repositories ${owner}/${repo}:`, error);
    return { success: false, error: error.message };
  }
}

module.exports = {
  listRepositories,
  getRepository,
  getRepositoryBranches,
  getRepositoryCommits,
  createRepository,
  updateRepository,
  deleteRepository,
  getCurrentUser,
  testConnection,
  getAuthenticatedCloneUrl,
  getSafeCloneUrl,
  GITEA_URL,
  GITEA_ORG
};
