// git-data-service.ts
// Interface and implementation for fetching Git data

import { DiffFile, GitLogEntry } from "../types";

// Re-export DiffFile as GitDiffFile
export type GitDiffFile = DiffFile;

/**
 * Interface for Git data services
 */
export interface GitDataService {
  /**
   * Fetches recent commit history
   * @param initialCommit The initial commit hash to start from
   * @returns List of commits
   */
  getCommitHistory(initialCommit?: string): Promise<GitLogEntry[]>;

  /**
   * Fetches diff between two commits
   * @param from Starting commit hash
   * @param to Ending commit hash (can be empty string for unstaged changes)
   * @returns List of changed files
   */
  getDiff(from: string, to: string): Promise<GitDiffFile[]>;

  /**
   * Fetches diff for a single commit
   * @param commit Commit hash
   * @returns List of changed files
   */
  getCommitDiff(commit: string): Promise<GitDiffFile[]>;

  /**
   * Fetches file content from git using a file hash
   * @param fileHash Git blob hash of the file to fetch
   * @returns File content as string
   */
  getFileContent(fileHash: string): Promise<string>;

  /**
   * Gets file content from the current working directory
   * @param filePath Path to the file within the repository
   * @returns File content as string
   */
  getWorkingCopyContent(filePath: string): Promise<string>;

  /**
   * Saves file content to the working directory
   * @param filePath Path to the file within the repository
   * @param content New content to save to the file
   */
  saveFileContent(filePath: string, content: string): Promise<void>;

  /**
   * Gets the base commit reference (often "sketch-base")
   * @returns Base commit reference
   */
  getBaseCommitRef(): Promise<string>;

  /**
   * Fetches unstaged changes (diff between a commit and working directory)
   * @param from Starting commit hash (defaults to HEAD if not specified)
   * @returns List of changed files
   */
  getUnstagedChanges(from?: string): Promise<GitDiffFile[]>;

  /**
   * Fetches list of untracked files in the repository
   * @returns List of untracked file paths
   */
  getUntrackedFiles(): Promise<string[]>;
}

/**
 * Default implementation of GitDataService for the real application
 */
export class DefaultGitDataService implements GitDataService {
  private baseCommitRef: string | null = null;

  async getCommitHistory(initialCommit?: string): Promise<GitLogEntry[]> {
    try {
      const url = initialCommit
        ? `git/recentlog?initialCommit=${encodeURIComponent(initialCommit)}`
        : "git/recentlog";
      const response = await fetch(url);

      if (!response.ok) {
        throw new Error(
          `Failed to fetch commit history: ${response.statusText}`,
        );
      }

      return await response.json();
    } catch (error) {
      console.error("Error fetching commit history:", error);
      throw error;
    }
  }

  async getDiff(from: string, to: string): Promise<GitDiffFile[]> {
    try {
      const url = `git/rawdiff?from=${encodeURIComponent(from)}&to=${encodeURIComponent(to)}`;
      const response = await fetch(url);

      if (!response.ok) {
        throw new Error(`Failed to fetch diff: ${response.statusText}`);
      }

      return await response.json();
    } catch (error) {
      console.error("Error fetching diff:", error);
      throw error;
    }
  }

  async getCommitDiff(commit: string): Promise<GitDiffFile[]> {
    try {
      const url = `git/rawdiff?commit=${encodeURIComponent(commit)}`;
      const response = await fetch(url);

      if (!response.ok) {
        throw new Error(`Failed to fetch commit diff: ${response.statusText}`);
      }

      return await response.json();
    } catch (error) {
      console.error("Error fetching commit diff:", error);
      throw error;
    }
  }

  async getFileContent(fileHash: string): Promise<string> {
    try {
      // If the hash is marked as a working copy (special value '000000' or empty)
      if (
        fileHash === "0000000000000000000000000000000000000000" ||
        !fileHash
      ) {
        // This shouldn't happen, but if it does, return empty string
        // Working copy content should be fetched through getWorkingCopyContent
        console.warn(
          "Invalid file hash for getFileContent, returning empty string",
        );
        return "";
      }

      const url = `git/show?hash=${encodeURIComponent(fileHash)}`;
      const response = await fetch(url);

      if (!response.ok) {
        throw new Error(`Failed to fetch file content: ${response.statusText}`);
      }

      const data = await response.json();
      return data.output || "";
    } catch (error) {
      console.error("Error fetching file content:", error);
      throw error;
    }
  }

  async getWorkingCopyContent(filePath: string): Promise<string> {
    try {
      const url = `git/cat?path=${encodeURIComponent(filePath)}`;
      const response = await fetch(url);

      if (!response.ok) {
        const errorText = await response.text();
        throw new Error(
          `Failed to fetch working copy content (${response.status}): ${errorText}`,
        );
      }
      if (response.status === 204) {
        return ""; // file doesn't exist
      }

      const data = await response.json();
      return data.output || "";
    } catch (error) {
      console.error("Error fetching working copy content:", error);
      throw error;
    }
  }

  async saveFileContent(filePath: string, content: string): Promise<void> {
    try {
      const url = `git/save`;
      const response = await fetch(url, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          path: filePath,
          content: content,
        }),
      });

      if (!response.ok) {
        const errorText = await response.text();
        throw new Error(
          `Failed to save file content: ${response.statusText} - ${errorText}`,
        );
      }

      // Don't need to return the response, just ensure it was successful
    } catch (error) {
      console.error("Error saving file content:", error);
      throw error;
    }
  }

  async getUnstagedChanges(from: string = "HEAD"): Promise<GitDiffFile[]> {
    try {
      // To get unstaged changes, we diff the specified commit (or HEAD) with an empty 'to'
      return await this.getDiff(from, "");
    } catch (error) {
      console.error("Error fetching unstaged changes:", error);
      throw error;
    }
  }

  async getBaseCommitRef(): Promise<string> {
    // Cache the base commit reference to avoid multiple requests
    if (this.baseCommitRef) {
      return this.baseCommitRef;
    }

    try {
      // This could be replaced with a specific endpoint call if available
      // For now, we'll use a fixed value or try to get it from the server
      this.baseCommitRef = "sketch-base";
      return this.baseCommitRef;
    } catch (error) {
      console.error("Error fetching base commit reference:", error);
      throw error;
    }
  }

  async getUntrackedFiles(): Promise<string[]> {
    try {
      const response = await fetch("git/untracked");

      if (!response.ok) {
        throw new Error(
          `Failed to fetch untracked files: ${response.statusText}`,
        );
      }

      const data = await response.json();
      return data.untracked_files || [];
    } catch (error) {
      console.error("Error fetching untracked files:", error);
      throw error;
    }
  }
}
