import type { Vault } from "obsidian";
import ImageUploader from "../service/image-uploader";
import type { HaloSite } from "../settings";
import { extractImageReferences, getAbsolutePath, replaceImagePaths } from "../utils/image";

export class ImageService {
  private uploader: ImageUploader;

  constructor(site: HaloSite) {
    this.uploader = new ImageUploader(site.url, site.token);
  }

  async uploadLocalImages(
    content: string,
    vault: Vault,
    currentFilePath: string,
  ): Promise<{ processedContent: string; successCount: number; failCount: number }> {
    const imageReferences = extractImageReferences(content);

    if (imageReferences.length === 0) {
      return { processedContent: content, successCount: 0, failCount: 0 };
    }

    const localImages = imageReferences.filter(
      (ref) => !ref.path.startsWith("http://") && !ref.path.startsWith("https://") && !ref.path.startsWith("data:"),
    );

    if (localImages.length === 0) {
      return { processedContent: content, successCount: 0, failCount: 0 };
    }

    const absolutePaths = localImages
      .map((ref) => ({
        original: ref.path,
        absolute: getAbsolutePath(vault, ref.path, currentFilePath),
      }))
      .filter((item) => item.absolute !== null) as { original: string; absolute: string }[];

    if (absolutePaths.length === 0) {
      return { processedContent: content, successCount: 0, failCount: 0 };
    }

    const pathMapping = await this.uploader.uploadImages(
      absolutePaths.map((item) => item.absolute),
      vault,
    );

    if (pathMapping.size === 0) {
      return { processedContent: content, successCount: 0, failCount: absolutePaths.length };
    }

    const mapping = new Map<string, string>();
    absolutePaths.forEach((item) => {
      const remoteUrl = pathMapping.get(item.absolute);
      if (remoteUrl) {
        mapping.set(item.original, remoteUrl);
      }
    });

    const processedContent = replaceImagePaths(content, mapping);
    const successCount = mapping.size;
    const failCount = absolutePaths.length - successCount;

    return { processedContent, successCount, failCount };
  }
}
