import * as plugins from './plugins.js';
import * as paths from './paths.js';

// Function to generate nav links from a folder
export async function generateNavLinks(projectName: string) {
  const folderPath = plugins.path.join(paths.docsDir, projectName);
  try {
    let files = await plugins.fs.readdir(folderPath);
    files = files.filter((file) => file.endsWith('.md')); // Only include Markdown files
    const navLinks: {
      text: string;
      link: string;
    }[] = [];
    for (const file of files) {
      const name = plugins.path.basename(file, '.md');
      const fileContent = await plugins.fs.readFile(plugins.path.join(folderPath, file), 'utf8');
      const smartfmInstance = new plugins.smartfm.Smartfm({
        fmType: 'yaml'
      });
      const frontmatter = smartfmInstance.parse(fileContent);
      let title = name;
      if (frontmatter.data.title) {
        title = frontmatter.data.title;
      }
      navLinks.push({
        text: title,
        link: `/${projectName}/${name}`,
      });
    }
    return navLinks;
  } catch (error) {
    console.error(`Error reading folder ${folderPath}:`, error);
    return [];
  }
}

/**
 * Downloads README files from all repositories within a specified Gitea organization.
 *
 * @param domain - The domain of the Gitea instance (e.g., "https://gitea.example.com").
 * @param org - The name of the organization whose repositories will be processed.
 * @param outputDir - The directory where README files will be saved. Defaults to "./readmes".
 * @param authToken - (Optional) Personal access token for authenticated requests.
 */
export async function downloadReadmes(
  domain: string,
  org: string,
  outputDir: string = './readmes',
  authToken?: string
): Promise<void> {
  // Ensure the output directory exists
  await plugins.fs.mkdir(outputDir, { recursive: true });

  // Helper function to construct headers
  const getHeaders = (additionalHeaders: Record<string, string> = {}) => {
    const headers: Record<string, string> = {
      'Content-Type': 'application/json',
      ...additionalHeaders,
    };
    if (authToken) {
      headers['Authorization'] = `token ${authToken}`;
    }
    return headers;
  };

  try {
    let page = 1;
    const perPage = 50; // Adjust as needed
    let hasMore = true;
    const repos: any[] = [];

    console.log(`Fetching repositories for organization: ${org}`);

    // Fetch all repositories with pagination
    while (hasMore) {
      const reposUrl = new URL(`/api/v1/orgs/${encodeURIComponent(org)}/repos`, domain);
      reposUrl.searchParams.append('page', page.toString());
      reposUrl.searchParams.append('limit', perPage.toString());

      const reposResponse = await fetch(reposUrl.toString(), {
        method: 'GET',
        headers: getHeaders(),
      });

      if (!reposResponse.ok) {
        throw new Error(
          `Failed to fetch repositories: ${reposResponse.status} ${reposResponse.statusText}`
        );
      }

      const fetchedRepos = await reposResponse.json();
      repos.push(...fetchedRepos);

      if (fetchedRepos.length < perPage) {
        hasMore = false;
      } else {
        page += 1;
      }
    }

    console.log(`Total repositories found: ${repos.length}`);

    for (const repo of repos) {
      const repoName: string = repo.name;
      console.log(`Processing repository: ${repoName}`);

      try {
        const readmeUrl = new URL(
          `/api/v1/repos/${encodeURIComponent(org)}/${encodeURIComponent(
            repoName
          )}/contents/readme.md`,
          domain
        );

        console.log(readmeUrl.toString());

        const readmeResponse = await fetch(readmeUrl.toString(), {
          method: 'GET',
          headers: getHeaders({
            Accept: 'application/vnd.gitea.raw',
          }),
        });

        if (readmeResponse.status === 404) {
          console.warn(`README not found for repository: ${repoName}`);
          continue;
        }

        if (!readmeResponse.ok) {
          throw new Error(
            `Failed to fetch README: ${readmeResponse.status} ${readmeResponse.statusText}`
          );
        }

        const readmeContentResponseObject: any = JSON.parse(await readmeResponse.text());
        let readmeContent = atob(readmeContentResponseObject.content);
        readmeContent = `---
title: "@${org}/${repo.name}"
---
${readmeContent}`;
        const sanitizedRepoName = repoName.replace(/[^a-z0-9_\-]/gi, '_'); // Sanitize filename
        const readmePath = plugins.path.join(outputDir, `${sanitizedRepoName}_readme.md`);

        await plugins.fs.writeFile(readmePath, readmeContent, 'utf8');
        console.log(`Saved README for ${repoName} to ${readmePath}`);
      } catch (readmeError: any) {
        console.error(`Error fetching README for repository: ${repoName}`, readmeError.message);
      }
    }

    console.log('All READMEs have been processed.');
  } catch (error: any) {
    console.error('An error occurred while fetching repositories:', error.message);
  }
}
