import { success, error, warn, info, blockSuccess, blockError, blockWarn, blockInfo, file } from "./lines";
import { logger } from "../util";

// Mock the logger function
jest.mock("../util", () => ({
  ...jest.requireActual("../util"),
  logger: jest.fn(),
  green: (text: string) => `[green]${text}[/green]`,
  red: (text: string) => `[red]${text}[/red]`,
  yellow: (text: string) => `[yellow]${text}[/yellow]`,
  blue: (text: string) => `[blue]${text}[/blue]`,
  spaces: jest.requireActual("../util").spaces,
  breakText: jest.requireActual("../util").breakText
}));

describe("Line Module Tests", () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  describe("Standard Line Functions", () => {
    it("success should log message with green checkmark", () => {
      success("Test success");
      expect(logger).toHaveBeenCalledWith("[green]✔[/green] Test success", {});
    });

    it("error should log message with red X", () => {
      error("Test error");
      expect(logger).toHaveBeenCalledWith("[red]×[/red] Test error", {});
    });

    it("warn should log message with yellow exclamation", () => {
      warn("Test warning");
      expect(logger).toHaveBeenCalledWith("[yellow]![/yellow] Test warning", {});
    });

    it("info should log message without prefix", () => {
      info("Test info");
      expect(logger).toHaveBeenCalledWith("[blue]i[/blue] Test info", {});
    });

    it("should handle array of messages", () => {
      success(["Line 1", "Line 2"]);
      expect(logger).toHaveBeenCalledWith("[green]✔[/green] Line 1", {});
      expect(logger).toHaveBeenCalledWith("   Line 2", {});
    });
  });

  describe("Block Line Functions", () => {
    it("blockSuccess should log message with green checkmark in block style", () => {
      blockSuccess("Test block success");
      expect(logger).toHaveBeenCalledWith("[green]✔[/green] Test block success", { useBlock: true });
    });

    it("blockError should log message with red X in block style", () => {
      blockError("Test block error");
      expect(logger).toHaveBeenCalledWith("[red]×[/red] Test block error", { useBlock: true });
    });

    it("blockWarn should log message with yellow exclamation in block style", () => {
      blockWarn("Test block warning");
      expect(logger).toHaveBeenCalledWith("[yellow]![/yellow] Test block warning", { useBlock: true });
    });

    it("blockInfo should log message without prefix in block style", () => {
      blockInfo("Test block info");
      expect(logger).toHaveBeenCalledWith("[blue]i[/blue] Test block info", { useBlock: true });
    });

    it("should handle array of messages in block style", () => {
      blockSuccess(["Block Line 1", "Block Line 2"]);
      expect(logger).toHaveBeenCalledWith("[green]✔[/green] Block Line 1", { useBlock: true });
      expect(logger).toHaveBeenCalledWith("   Block Line 2", { useBlock: true });
    });
  });

  describe("File Function", () => {
    beforeEach(() => {
      jest.clearAllMocks();
    });

    it("should handle a single file path with programming language extension", () => {
      file("test.ts");
      expect(logger).toHaveBeenCalledWith("📜 test.ts", expect.any(Object));

      file("script.py");
      expect(logger).toHaveBeenCalledWith("🐍 script.py", expect.any(Object));

      file("app.js");
      expect(logger).toHaveBeenCalledWith("📜 app.js", expect.any(Object));
    });

    it("should handle document file types", () => {
      file("document.md");
      expect(logger).toHaveBeenCalledWith("📝 document.md", expect.any(Object));

      file("report.pdf");
      expect(logger).toHaveBeenCalledWith("📕 report.pdf", expect.any(Object));

      file("notes.txt");
      expect(logger).toHaveBeenCalledWith("📄 notes.txt", expect.any(Object));
    });

    it("should handle media file types", () => {
      file("image.png");
      expect(logger).toHaveBeenCalledWith("🖼 image.png", expect.any(Object));

      file("video.mp4");
      expect(logger).toHaveBeenCalledWith("🎥 video.mp4", expect.any(Object));

      file("audio.mp3");
      expect(logger).toHaveBeenCalledWith("🎵 audio.mp3", expect.any(Object));
    });

    it("should handle archive file types", () => {
      file("archive.zip");
      expect(logger).toHaveBeenCalledWith("📦 archive.zip", expect.any(Object));

      file("backup.tar.gz");
      expect(logger).toHaveBeenCalledWith("📦 backup.tar.gz", expect.any(Object));
    });

    it("should handle multiple file paths with different extensions", () => {
      file(["app.js", "doc.pdf", "image.png"]);
      expect(logger).toHaveBeenCalledTimes(3);
      expect(logger).toHaveBeenNthCalledWith(1, "📜 app.js", expect.any(Object));
      expect(logger).toHaveBeenNthCalledWith(2, "📕 doc.pdf", expect.any(Object));
      expect(logger).toHaveBeenNthCalledWith(3, "🖼 image.png", expect.any(Object));
    });

    it("should handle files without extension", () => {
      file("README");
      expect(logger).toHaveBeenCalledWith("📄 README", expect.any(Object));
    });

    it("should respect pathDepth option", () => {
      file("path/to/deep/file.ts", { pathDepth: 2 });
      expect(logger).toHaveBeenCalledWith("📜 deep/file.ts", expect.any(Object));
    });

    it("should not modify path when pathDepth is greater than path segments", () => {
      file("shallow/file.ts", { pathDepth: 5 });
      expect(logger).toHaveBeenCalledWith("📜 shallow/file.ts", expect.any(Object));
    });

    it("should handle pathDepth of 0 or undefined", () => {
      const fullPath = "very/deep/path/structure/file.ts";
      file(fullPath, { pathDepth: 0 });
      expect(logger).toHaveBeenCalledWith("📜 very/deep/path/structure/file.ts", expect.any(Object));

      file(fullPath);
      expect(logger).toHaveBeenCalledWith("📜 very/deep/path/structure/file.ts", expect.any(Object));
    });
  });

  describe("Line Options Handling", () => {
    it("should respect custom options", () => {
      const customOptions = { indent: 2, useBlock: false };
      success("Test with options", {  indent: 2, useBlock: false,});
      expect(logger).toHaveBeenCalledWith("  [green]✔[/green] Test with options", customOptions);
    });

    it("should handle null message", () => {
      info(null);
      expect(logger).toHaveBeenCalledWith("", {});
    });
  });
});
