// app/lib/__tests__/whisper.spec.tsx

import React from "react";
import { getDb } from "@/app/lib/db";
import { WhisperFile, WhisperModelTag } from "@/app/lib/whisper"; // Corrected to use WhisperFile and WhisperModelTag instead of WhisperDownloader
import { Settings } from "@/app/lib/settings";
import { File } from "expo-file-system/next";
jest.mock('expo-file-system');
import * as FileSystem from 'expo-file-system';

jest.mock("@/app/lib/db", () => ({
  getDb: jest.fn().mockResolvedValue({
    runAsync: jest.fn(),
    upsert: jest.fn(), // Mock the upsert method used in addToDatabase
  }),
}));

jest.mock("@/app/lib/settings", () => ({
  Settings: {
    getDefault: jest.fn(() => ({
      getValue: jest.fn((key) => {
        switch (key) {
          case "whisper_model":
            return "base";
          default:
            throw new Error(`Invalid setting: '${key}'`);
        }
      }),
    })),
  },
}));


jest.mock("expo-file-system/next", () => {
  const _next = jest.requireActual("expo-file-system/next");
  return {
    ..._next,
    File: jest.fn().mockImplementation(() => ({
      ..._next.File,
      text: jest.fn(() => {
        return new String("text");
      }),
    })),
  };
});

describe("WhisperFile", () => {
  // Corrected to use WhisperFile instead of WhisperDownloader
  let whisperFile: WhisperFile;

  beforeEach(async () => {
    whisperFile = new WhisperFile("small");
  });

  it("should create a download resumable with existing data if available", async () => {
    const mockExistingData = "mockExistingData";
    jest.spyOn(whisperFile, "doesTargetExist").mockResolvedValue(true);

    await whisperFile.createDownloadResumable();
    // expect(whisperFile.targetFileName).toEqual("small.bin");
    expect(whisperFile.targetPath).toContain("small.bin");

    expect(FileSystem.createDownloadResumable).toHaveBeenCalledWith(
      "https://huggingface.co/openai/whisper-small/resolve/main/pytorch_model.bin",
      "file:///whisper/small.bin",
      {},
      expect.any(Function),
      expect.anything(),
    );
  });

  // it("should create a download resumable without existing data if not available", async () => {
  //   jest.spyOn(whisperFile, "doesTargetExist").mockResolvedValue(false);

  //   await whisperFile.createDownloadResumable(); // Updated to use createDownloadResumable instead of download

  //   expect(FileSystem.createDownloadResumable).toHaveBeenCalledWith(
  //     "http://mock.model.com/model",
  //     "mockTargetPath",
  //     {},
  //     expect.any(Function),
  //     undefined
  //   );
  // });

  // it("should update the download status in the database", async () => {
  //   const mockRunAsync = jest.fn();
  //   (getDb as jest.Mock).mockResolvedValue({ runAsync: mockRunAsync });

  //   const downloadable = await whisperFile.createDownloadResumable(); // Updated to use createDownloadResumable instead of download
  //   await downloadable.resumeAsync();

  //   jest.advanceTimersByTime(1000);

  //   expect(mockRunAsync).toHaveBeenCalled();
  // });

  // it("should record the latest target hash after downloading", async () => {
  //   const mockRecordLatestTargetHash = jest.spyOn(
  //     whisperFile,
  //     "recordLatestTargetHash"
  //   );

  //   await whisperFile.createDownloadResumable(); // Updated to use createDownloadResumable instead of download

  //   expect(mockRecordLatestTargetHash).toHaveBeenCalled();
  // });

  // it("should call the onData callback if provided", async () => {
  //   const mockOnData = jest.fn();
  //   const options = { onData: mockOnData };

  //   await whisperFile.createDownloadResumable(options); // Updated to use createDownloadResumable instead of download

  //   expect(mockOnData).toHaveBeenCalledWith(expect.any(Object));
  // });

  // describe("getDownloadStatus", () => {
  //   it("should return the correct download status when model size is known and download has started", async () => {
  //     whisperFile.size = 1024;
  //     jest.spyOn(whisperFile, "doesTargetExist").mockResolvedValue(true);
  //     jest.spyOn(whisperFile, "isDownloadComplete").mockResolvedValue(false);
  //     jest.spyOn(whisperFile, "targetFile").mockReturnValue({
  //       size: 512,
  //     });

  //     const status = await whisperFile.getDownloadStatus();

  //     expect(status).toEqual({
  //       doesTargetExist: true,
  //       isDownloadComplete: false,
  //       hasDownloadStarted: true,
  //       progress: {
  //         current: 512,
  //         total: 1024,
  //         remaining: 512,
  //         percentRemaining: 50.0,
  //       },
  //     });
  //   });

  //   it("should return the correct download status when model size is known and download is complete", async () => {
  //     whisperFile.size = 1024;
  //     jest.spyOn(whisperFile, "doesTargetExist").mockResolvedValue(true);
  //     jest.spyOn(whisperFile, "isDownloadComplete").mockResolvedValue(true);

  //     const status = await whisperFile.getDownloadStatus();

  //     expect(status).toEqual({
  //       doesTargetExist: true,
  //       isDownloadComplete: true,
  //       hasDownloadStarted: false,
  //       progress: undefined,
  //     });
  //   });

  //   it("should return the correct download status when model size is unknown", async () => {
  //     jest.spyOn(whisperFile, "doesTargetExist").mockResolvedValue(false);

  //     const status = await whisperFile.getDownloadStatus();

  //     expect(status).toEqual({
  //       doesTargetExist: false,
  //       isDownloadComplete: false,
  //       hasDownloadStarted: false,
  //       progress: undefined,
  //     });
  //   });
  // });
});
