local hex = require("ccc.output.hex")
local hex_short = require("ccc.output.hex_short")
local css_rgb = require("ccc.output.css_rgb")
local css_hsl = require("ccc.output.css_hsl")
local css_hwb = require("ccc.output.css_hwb")
local css_lab = require("ccc.output.css_lab")
local css_lch = require("ccc.output.css_lch")
local css_oklab = require("ccc.output.css_oklab")
local css_oklch = require("ccc.output.css_oklch")
local float = require("ccc.output.float")

---@param colorOutput ccc.ColorOutput
---@param RGB integer[] # range in (0, 255)
---@param A? Alpha
---@param expected string
local function output_test(colorOutput, RGB, A, expected)
  RGB = vim.tbl_map(function(x)
    return x / 255
  end, RGB)
  local actual = colorOutput.str(RGB, A)
  assert.are.equal(expected, actual, ("expected %s, but passed in %s"):format(expected, actual))
end

describe("output", function()
  describe("hex", function()
    it("only RGB", function()
      output_test(hex, { 255, 0, 0 }, nil, "#ff0000")
    end)
    it("with Alpha", function()
      output_test(hex, { 255, 0, 0 }, 1, "#ff0000ff")
    end)
  end)

  describe("hex_short", function()
    it("only RGB", function()
      output_test(hex_short, { 255, 0, 0 }, nil, "#f00")
    end)
    it("with Alpha", function()
      output_test(hex_short, { 255, 0, 0 }, 1, "#f00f")
    end)
  end)

  describe("css_rgb", function()
    it("only RGB", function()
      output_test(css_rgb, { 255, 0, 0 }, nil, "rgb(255 0 0)")
    end)
    it("with Alpha", function()
      output_test(css_rgb, { 255, 0, 0 }, 1, "rgb(255 0 0 / 100%)")
    end)
  end)

  describe("css_hsl", function()
    it("only RGB", function()
      output_test(css_hsl, { 255, 0, 0 }, nil, "hsl(0 100% 50%)")
    end)
    it("with Alpha", function()
      output_test(css_hsl, { 255, 0, 0 }, 1, "hsl(0 100% 50% / 100%)")
    end)
  end)

  describe("css_hwb", function()
    it("only RGB", function()
      output_test(css_hwb, { 0, 0, 255 }, nil, "hwb(240 0% 0%)")
    end)
    it("with Alpha", function()
      output_test(css_hwb, { 0, 0, 255 }, 1, "hwb(240 0% 0% / 100%)")
    end)
  end)

  describe("css_lab", function()
    it("only RGB", function()
      output_test(css_lab, { 128, 128, 128 }, nil, "lab(54% 0 0)")
    end)
    it("with Alpha", function()
      output_test(css_lab, { 128, 128, 128 }, 1, "lab(54% 0 0 / 100%)")
    end)
  end)

  describe("css_lch", function()
    it("only RGB", function()
      output_test(css_lch, { 255, 0, 0 }, nil, "lch(53% 105 40)")
    end)
    it("with Alpha", function()
      output_test(css_lch, { 255, 0, 0 }, 1, "lch(53% 105 40 / 100%)")
    end)
  end)

  describe("css_hsl", function()
    it("only RGB", function()
      output_test(css_hsl, { 255, 0, 0 }, nil, "hsl(0 100% 50%)")
    end)
    it("with Alpha", function()
      output_test(css_hsl, { 255, 0, 0 }, 1, "hsl(0 100% 50% / 100%)")
    end)
  end)

  describe("css_oklab", function()
    it("only RGB", function()
      output_test(css_oklab, { 255, 0, 0 }, nil, "oklab(63% 0.22 0.13)")
    end)
    it("with Alpha", function()
      output_test(css_oklab, { 255, 0, 0 }, 1, "oklab(63% 0.22 0.13 / 100%)")
    end)
  end)

  describe("css_oklch", function()
    it("only RGB", function()
      output_test(css_oklch, { 255, 0, 0 }, nil, "oklch(63% 0.26 29)")
    end)
    it("with Alpha", function()
      output_test(css_oklch, { 255, 0, 0 }, 1, "oklch(63% 0.26 29 / 100%)")
    end)
  end)

  describe("float", function()
    it("only RGB", function()
      output_test(float, { 255, 0, 0 }, nil, "(1.000,0.000,0.000)")
    end)
    it("with Alpha", function()
      output_test(float, { 255, 0, 0 }, 1, "(1.000,0.000,0.000,1.000)")
    end)
  end)
end)
