defmodule BerrypodWeb.PageRendererTest do
  use BerrypodWeb.ConnCase, async: false

  import Phoenix.LiveViewTest

  alias Berrypod.Pages
  alias Berrypod.Settings.ThemeSettings
  alias BerrypodWeb.PageRenderer

  # Minimal assigns that every page needs (the stuff shop_layout requires)
  defp base_assigns do
    %{
      __changed__: nil,
      theme_settings: %ThemeSettings{},
      site_name: "Test Store",
      logo_image: nil,
      header_image: nil,
      mode: :shop,
      cart_items: [],
      cart_count: 0,
      cart_subtotal: "£0.00",
      cart_total: nil,
      cart_drawer_open: false,
      cart_status: nil,
      is_admin: false,
      search_query: "",
      search_results: [],
      search_open: false,
      categories: [],
      shipping_estimate: nil,
      country_code: "GB",
      available_countries: [],
      flash: %{}
    }
  end

  defp render_page(slug, extra_assigns \\ %{}) do
    page = Pages.get_page(slug)

    assigns =
      base_assigns()
      |> Map.merge(extra_assigns)
      |> Map.put(:page, page)

    PageRenderer.render_page(assigns)
    |> rendered_to_string()
  end

  describe "render_page/1" do
    test "home page renders hero and featured products" do
      html = render_page("home", %{products: []})

      assert html =~ "Your headline goes here"
      assert html =~ "Shop the collection"
      assert html =~ "Featured products"
      assert html =~ "Your story in a nutshell"
    end

    test "about page renders hero and content area" do
      html =
        render_page("about", %{content_blocks: [%{type: :paragraph, text: "Test about text"}]})

      assert html =~ "About us"
      assert html =~ "content-body"
    end

    test "delivery page renders hero" do
      html = render_page("delivery", %{content_blocks: []})

      assert html =~ "Delivery &amp; returns"
    end

    test "privacy page renders hero" do
      html = render_page("privacy", %{content_blocks: []})

      assert html =~ "Privacy policy"
    end

    test "terms page renders hero" do
      html = render_page("terms", %{content_blocks: []})

      assert html =~ "Terms of service"
    end

    test "contact page renders hero, form, and sidebar blocks" do
      html = render_page("contact", %{tracking_state: :idle})

      assert html =~ "Get in touch"
      assert html =~ "Send a message"
      assert html =~ "Track your order"
      assert html =~ "Handy to know"
      assert html =~ "Newsletter"
    end

    test "collection page renders header, filter bar, and grid" do
      html = render_page("collection", %{products: [], collection_title: "All Products"})

      assert html =~ "All Products"
      assert html =~ "filter-bar"
    end

    test "pdp page renders breadcrumb and product hero when product provided" do
      product = %{
        id: "test-id",
        title: "Test Product",
        slug: "test-product",
        category: "Art Prints",
        description: "A lovely test product",
        cheapest_price: 2500,
        compare_at_price: nil,
        on_sale: false,
        in_stock: true,
        provider_data: %{}
      }

      html =
        render_page("pdp", %{
          product: product,
          gallery_images: [],
          display_price: 2500,
          selected_variant: nil,
          option_types: [],
          selected_options: %{},
          available_options: %{},
          option_urls: %{},
          quantity: 1,
          related_products: [],
          reviews: [],
          average_rating: 5,
          total_count: 0
        })

      assert html =~ "Art Prints"
      assert html =~ "Test Product"
      assert html =~ "pdp-grid"
      assert html =~ "Add to basket"
    end

    test "cart page renders empty state when no items" do
      html = render_page("cart")

      assert html =~ "Your basket"
      assert html =~ "cart-empty"
    end

    test "cart page renders items when present" do
      items = [
        %{
          variant_id: "v1",
          name: "Test T-Shirt",
          variant: "Black / M",
          price: 2500,
          quantity: 1,
          image: nil,
          product_id: "test-t-shirt",
          in_stock: true
        }
      ]

      html =
        render_page("cart", %{
          cart_items: items,
          cart_count: 1,
          cart_subtotal: "£25.00",
          cart_page_subtotal: 2500
        })

      assert html =~ "Your basket"
      assert html =~ "cart-page-list"
    end

    test "search page renders search form" do
      html = render_page("search", %{search_page_query: "", search_page_results: []})

      assert html =~ "Search"
      assert html =~ ~s(name="q")
      assert html =~ "Search products..."
    end

    test "checkout success renders pending state when no order" do
      html = render_page("checkout_success", %{order: nil})

      assert html =~ "Processing your payment"
    end

    test "orders page renders empty state when orders nil" do
      html = render_page("orders", %{orders: nil, lookup_email: nil})

      assert html =~ "Your orders"
      assert html =~ "expired or is invalid"
    end

    test "orders page renders no orders message" do
      html = render_page("orders", %{orders: [], lookup_email: "test@example.com"})

      assert html =~ "test@example.com"
      assert html =~ "No orders found"
    end

    test "order detail page renders nothing when no order" do
      html = render_page("order_detail", %{order: nil})

      # Should not crash, just render empty
      assert html =~ "main"
    end

    test "error page renders error hero" do
      html =
        render_page("error", %{
          error_code: "404",
          error_title: "Page not found",
          error_description: "Sorry, we couldn't find that page.",
          products: []
        })

      assert html =~ "404"
      assert html =~ "Page not found"
      assert html =~ "Go to Homepage"
    end
  end

  describe "page_main_class/1" do
    test "returns correct classes for each page" do
      assert PageRenderer.page_main_class("contact") == "page-container contact-main"
      assert PageRenderer.page_main_class("cart") == "page-container"
      assert PageRenderer.page_main_class("checkout_success") == "page-container checkout-main"
      assert PageRenderer.page_main_class("orders") == "page-container orders-main"
      assert PageRenderer.page_main_class("order_detail") == "page-container order-detail-main"
      assert PageRenderer.page_main_class("error") == "error-main"
      assert PageRenderer.page_main_class("about") == "content-page"
      assert PageRenderer.page_main_class("home") == nil
    end
  end

  describe "utility blocks" do
    setup do
      on_exit(fn ->
        import Ecto.Query
        Berrypod.Repo.delete_all(from p in Berrypod.Pages.Page, where: p.slug == "home")
        Berrypod.Pages.PageCache.invalidate_all()
      end)

      :ok
    end

    test "spacer block renders with size" do
      {:ok, _} =
        Pages.save_page("home", %{
          title: "Home",
          blocks: [%{"id" => "blk_sp", "type" => "spacer", "settings" => %{"size" => "large"}}]
        })

      html = render_page("home", %{products: []})

      assert html =~ ~s(class="block-spacer")
      assert html =~ ~s(data-size="large")
    end

    test "divider block renders with style" do
      {:ok, _} =
        Pages.save_page("home", %{
          title: "Home",
          blocks: [%{"id" => "blk_dv", "type" => "divider", "settings" => %{"style" => "dots"}}]
        })

      html = render_page("home", %{products: []})

      assert html =~ ~s(class="block-divider")
      assert html =~ ~s(data-style="dots")
    end

    test "button block renders themed link" do
      {:ok, _} =
        Pages.save_page("home", %{
          title: "Home",
          blocks: [
            %{
              "id" => "blk_btn",
              "type" => "button",
              "settings" => %{
                "text" => "Shop now",
                "href" => "/collections/all",
                "style" => "primary",
                "alignment" => "centre"
              }
            }
          ]
        })

      html = render_page("home", %{products: []})

      assert html =~ "Shop now"
      assert html =~ ~s(data-align="centre")
      assert html =~ "themed-button"
    end

    test "video embed renders YouTube iframe" do
      {:ok, _} =
        Pages.save_page("home", %{
          title: "Home",
          blocks: [
            %{
              "id" => "blk_vid",
              "type" => "video_embed",
              "settings" => %{
                "url" => "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
                "caption" => "Demo video"
              }
            }
          ]
        })

      html = render_page("home", %{products: []})

      assert html =~ "youtube-nocookie.com/embed/dQw4w9WgXcQ"
      assert html =~ "Demo video"
      assert html =~ "video-embed"
    end

    test "video embed renders Vimeo iframe" do
      {:ok, _} =
        Pages.save_page("home", %{
          title: "Home",
          blocks: [
            %{
              "id" => "blk_vim",
              "type" => "video_embed",
              "settings" => %{"url" => "https://vimeo.com/123456789"}
            }
          ]
        })

      html = render_page("home", %{products: []})

      assert html =~ "player.vimeo.com/video/123456789"
    end

    test "video embed shows fallback link for unknown URLs" do
      {:ok, _} =
        Pages.save_page("home", %{
          title: "Home",
          blocks: [
            %{
              "id" => "blk_unk",
              "type" => "video_embed",
              "settings" => %{"url" => "https://example.com/video", "caption" => "My video"}
            }
          ]
        })

      html = render_page("home", %{products: []})

      assert html =~ "video-embed-fallback"
      assert html =~ "My video"
      refute html =~ "<iframe"
    end
  end

  describe "format_order_status/1" do
    test "maps status strings to display text" do
      assert PageRenderer.format_order_status("unfulfilled") == "Being prepared"
      assert PageRenderer.format_order_status("shipped") == "On its way"
      assert PageRenderer.format_order_status("delivered") == "Delivered"
      assert PageRenderer.format_order_status("unknown") == "unknown"
    end
  end
end
