defmodule SimpleshopThemeWeb.Shop.ProductShowTest do
  use SimpleshopThemeWeb.ConnCase, async: false

  import Phoenix.LiveViewTest
  import SimpleshopTheme.AccountsFixtures
  import SimpleshopTheme.ProductsFixtures

  alias SimpleshopTheme.Products

  setup do
    user_fixture()
    {:ok, _} = SimpleshopTheme.Settings.set_site_live(true)

    pc = provider_connection_fixture()

    # Art print with size options and 2 images (for gallery tests)
    print =
      product_fixture(%{
        provider_connection: pc,
        title: "Mountain Sunrise Print",
        category: "Art Prints",
        description: "A beautiful mountain sunrise art print",
        provider_data: %{
          "options" => [
            %{
              "name" => "Size",
              "type" => "size",
              "values" => [
                %{"title" => "8x10"},
                %{"title" => "12x18"},
                %{"title" => "18x24"}
              ]
            }
          ]
        }
      })

    product_variant_fixture(%{
      product: print,
      title: "8x10",
      price: 1999,
      options: %{"Size" => "8x10"}
    })

    product_variant_fixture(%{
      product: print,
      title: "12x18",
      price: 2400,
      options: %{"Size" => "12x18"}
    })

    product_variant_fixture(%{
      product: print,
      title: "18x24",
      price: 3200,
      options: %{"Size" => "18x24"}
    })

    product_image_fixture(%{
      product: print,
      position: 0,
      src: "https://example.com/print-1.jpg"
    })

    product_image_fixture(%{
      product: print,
      position: 1,
      src: "https://example.com/print-2.jpg"
    })

    Products.recompute_cached_fields(print)

    # T-shirt with colour + size options (some sizes unavailable in white)
    shirt =
      product_fixture(%{
        provider_connection: pc,
        title: "Forest T-Shirt",
        category: "Apparel",
        description: "A forest themed t-shirt",
        provider_data: %{
          "options" => [
            %{
              "name" => "Color",
              "type" => "color",
              "values" => [
                %{"title" => "Black", "colors" => ["#000000"]},
                %{"title" => "White", "colors" => ["#FFFFFF"]}
              ]
            },
            %{
              "name" => "Size",
              "type" => "size",
              "values" => [
                %{"title" => "M"},
                %{"title" => "L"},
                %{"title" => "XL"}
              ]
            }
          ]
        }
      })

    for color <- ["Black", "White"], size <- ["M", "L"] do
      product_variant_fixture(%{
        product: shirt,
        title: "#{color} / #{size}",
        price: 2999,
        options: %{"Color" => color, "Size" => size}
      })
    end

    # Black / XL available
    product_variant_fixture(%{
      product: shirt,
      title: "Black / XL",
      price: 2999,
      options: %{"Color" => "Black", "Size" => "XL"}
    })

    # White / XL unavailable
    product_variant_fixture(%{
      product: shirt,
      title: "White / XL",
      price: 2999,
      options: %{"Color" => "White", "Size" => "XL"},
      is_available: false
    })

    product_image_fixture(%{
      product: shirt,
      position: 0,
      src: "https://example.com/shirt-1.jpg"
    })

    Products.recompute_cached_fields(shirt)

    # Another art print for related products
    related =
      product_fixture(%{
        provider_connection: pc,
        title: "Ocean Waves Print",
        category: "Art Prints"
      })

    product_variant_fixture(%{
      product: related,
      title: "12x18",
      price: 2400,
      options: %{"Size" => "12x18"}
    })

    Products.recompute_cached_fields(related)

    %{print: print, shirt: shirt, related: related}
  end

  describe "Product detail page" do
    test "renders product page with product name", %{conn: conn, print: print} do
      {:ok, _view, html} = live(conn, ~p"/products/#{print.slug}")

      assert html =~ print.title
    end

    test "renders product description", %{conn: conn, print: print} do
      {:ok, _view, html} = live(conn, ~p"/products/#{print.slug}")

      assert html =~ print.description
    end

    test "renders product price", %{conn: conn, print: print} do
      {:ok, _view, html} = live(conn, ~p"/products/#{print.slug}")

      # Cheapest variant is 8x10 at £19.99
      assert html =~ "£19.99"
    end

    test "renders breadcrumb with category link", %{conn: conn, print: print} do
      {:ok, _view, html} = live(conn, ~p"/products/#{print.slug}")

      assert html =~ "Art Prints"
      assert html =~ "/collections/"
    end

    test "renders add to cart button", %{conn: conn, print: print} do
      {:ok, _view, html} = live(conn, ~p"/products/#{print.slug}")

      assert html =~ "Add to basket"
    end

    test "renders related products section", %{conn: conn, print: print, related: related} do
      {:ok, _view, html} = live(conn, ~p"/products/#{print.slug}")

      assert html =~ related.title
    end
  end

  describe "Variant selection" do
    test "renders variant selectors for product with size options", %{conn: conn, print: print} do
      {:ok, _view, html} = live(conn, ~p"/products/#{print.slug}")

      assert html =~ "Size"
      assert html =~ "8x10"
      assert html =~ "12x18"
      assert html =~ "18x24"
    end

    test "renders colour and size selectors for apparel", %{conn: conn, shirt: shirt} do
      {:ok, _view, html} = live(conn, ~p"/products/#{shirt.slug}")

      assert html =~ "Color"
      assert html =~ "Size"
    end

    test "selecting a size updates the price", %{conn: conn, print: print} do
      {:ok, view, _html} = live(conn, ~p"/products/#{print.slug}")

      html =
        view
        |> element("button[phx-value-value='18x24']")
        |> render_click()

      assert html =~ "£32.00"
    end

    test "selecting a colour updates available sizes", %{conn: conn, shirt: shirt} do
      {:ok, view, _html} = live(conn, ~p"/products/#{shirt.slug}")

      html =
        view
        |> element("button[aria-label='Select White']")
        |> render_click()

      # XL should be disabled (unavailable in white)
      assert html =~ "disabled"
    end

    test "shows variant for single-variant product", %{conn: conn, related: related} do
      {:ok, _view, html} = live(conn, ~p"/products/#{related.slug}")

      # Ocean Waves Print has no provider_data options, so shows "One size"
      assert html =~ "One size"
    end
  end

  describe "Quantity selector" do
    test "renders quantity selector with initial value of 1", %{conn: conn, print: print} do
      {:ok, view, _html} = live(conn, ~p"/products/#{print.slug}")

      assert has_element?(view, "button[phx-click='decrement_quantity']")
      assert has_element?(view, "button[phx-click='increment_quantity']")
    end

    test "decrement button is disabled at quantity 1", %{conn: conn, print: print} do
      {:ok, view, _html} = live(conn, ~p"/products/#{print.slug}")

      assert has_element?(view, "button[phx-click='decrement_quantity'][disabled]")
    end

    test "increment increases quantity", %{conn: conn, print: print} do
      {:ok, view, _html} = live(conn, ~p"/products/#{print.slug}")

      html =
        view
        |> element("button[phx-click='increment_quantity']")
        |> render_click()

      # Quantity now 2, decrement no longer disabled
      refute html =~ ~s(phx-click="decrement_quantity" disabled)
    end

    test "decrement decreases quantity", %{conn: conn, print: print} do
      {:ok, view, _html} = live(conn, ~p"/products/#{print.slug}")

      # Increment twice to get to 3
      view |> element("button[phx-click='increment_quantity']") |> render_click()
      view |> element("button[phx-click='increment_quantity']") |> render_click()

      html =
        view
        |> element("button[phx-click='decrement_quantity']")
        |> render_click()

      # Should be back to 2 — decrement still enabled
      refute html =~ ~s(phx-click="decrement_quantity" disabled)
    end

    test "quantity resets to 1 after adding to cart", %{conn: conn, print: print} do
      {:ok, view, _html} = live(conn, ~p"/products/#{print.slug}")

      # Increment to 3
      view |> element("button[phx-click='increment_quantity']") |> render_click()
      view |> element("button[phx-click='increment_quantity']") |> render_click()

      # Add to cart
      html =
        view
        |> element("button", "Add to basket")
        |> render_click()

      # Decrement should be disabled again (quantity reset to 1)
      assert html =~ ~s(phx-click="decrement_quantity")
      assert html =~ "disabled"
    end
  end

  describe "Add to cart" do
    test "add to cart opens the cart drawer", %{conn: conn, print: print} do
      {:ok, view, _html} = live(conn, ~p"/products/#{print.slug}")

      html =
        view
        |> element("button", "Add to basket")
        |> render_click()

      assert html =~ "added to cart"
    end

    test "add to cart shows product in cart drawer", %{conn: conn, print: print} do
      {:ok, view, _html} = live(conn, ~p"/products/#{print.slug}")

      html =
        view
        |> element("button", "Add to basket")
        |> render_click()

      assert html =~ "Mountain Sunrise Print"
    end
  end

  describe "Product gallery" do
    test "renders carousel with hook and accessibility attrs", %{conn: conn, print: print} do
      {:ok, _view, html} = live(conn, ~p"/products/#{print.slug}")

      assert html =~ ~s(phx-hook="ProductImageScroll")
      assert html =~ ~s(role="region")
      assert html =~ ~s(aria-label="Product images")
    end

    test "renders all gallery images with alt text", %{conn: conn, print: print} do
      {:ok, _view, html} = live(conn, ~p"/products/#{print.slug}")

      assert html =~ "#{print.title} — image 1 of"
      assert html =~ "#{print.title} — image 2 of"
    end

    test "renders dot indicators for multi-image gallery", %{conn: conn, print: print} do
      {:ok, view, _html} = live(conn, ~p"/products/#{print.slug}")

      assert has_element?(view, ".product-image-dots")
      assert has_element?(view, ".product-image-dot")
    end

    test "renders thumbnail grid for multi-image gallery", %{conn: conn, print: print} do
      {:ok, view, _html} = live(conn, ~p"/products/#{print.slug}")

      assert has_element?(view, ".pdp-gallery-thumbs")
      assert has_element?(view, ".pdp-thumbnail")
    end

    test "renders prev/next navigation arrows", %{conn: conn, print: print} do
      {:ok, view, _html} = live(conn, ~p"/products/#{print.slug}")

      assert has_element?(view, "button.pdp-nav-prev")
      assert has_element?(view, "button.pdp-nav-next")
      assert has_element?(view, ~s(button[aria-label="Previous image"]))
      assert has_element?(view, ~s(button[aria-label="Next image"]))
    end

    test "renders lightbox dialog", %{conn: conn, print: print} do
      {:ok, view, _html} = live(conn, ~p"/products/#{print.slug}")

      assert has_element?(view, "dialog#pdp-lightbox")
    end

    test "renders lightbox click target for desktop", %{conn: conn, print: print} do
      {:ok, view, _html} = live(conn, ~p"/products/#{print.slug}")

      assert has_element?(view, ".pdp-lightbox-click")
    end

    test "thumbnails have correct aria-labels", %{conn: conn, print: print} do
      {:ok, _view, html} = live(conn, ~p"/products/#{print.slug}")

      assert html =~ "View image 1 of"
      assert html =~ "View image 2 of"
    end
  end

  describe "Product gallery edge cases" do
    test "single image renders without carousel or dots", %{conn: conn, shirt: shirt} do
      {:ok, view, _html} = live(conn, ~p"/products/#{shirt.slug}")

      # Shirt has only 1 image — should render single view, not carousel
      assert has_element?(view, ".pdp-gallery-single")
      refute has_element?(view, ".product-image-dots")
    end
  end

  describe "Navigation" do
    test "product links navigate to correct product page", %{conn: conn, shirt: shirt} do
      {:ok, _view, html} = live(conn, ~p"/products/#{shirt.slug}")

      assert html =~ shirt.title
    end

    test "unknown slug redirects to collections", %{conn: conn} do
      assert {:error, {:live_redirect, %{to: "/collections/all"}}} =
               live(conn, ~p"/products/nonexistent")
    end
  end
end
