defmodule Mix.Tasks.GenerateMockups do
  @moduledoc """
  Generates product mockups using the Printify API.

  This task automates the creation of product mockups for the SimpleshopTheme
  sample content. It downloads artwork from Unsplash, uploads it to Printify,
  creates products, and downloads the generated mockups.

  ## Requirements

  - A Printify account with API access
  - The PRINTIFY_API_TOKEN environment variable must be set

  ## Usage

      # Generate mockups (keeps products in Printify)
      mix generate_mockups

      # Generate mockups and delete products afterwards
      mix generate_mockups --cleanup

      # Search for available blueprints
      mix generate_mockups --search "poster"

      # List all blueprints
      mix generate_mockups --list-blueprints

  ## Output

  Mockup images are saved to: priv/static/mockups/
  """

  use Mix.Task

  alias SimpleshopTheme.Mockups.Generator, as: MockupGenerator

  @shortdoc "Generates product mockups using Printify API"

  @impl Mix.Task
  def run(args) do
    # Start required applications
    Mix.Task.run("app.start")

    {opts, _, _} =
      OptionParser.parse(args,
        switches: [
          cleanup: :boolean,
          search: :string,
          list_blueprints: :boolean,
          help: :boolean
        ],
        aliases: [
          c: :cleanup,
          s: :search,
          l: :list_blueprints,
          h: :help
        ]
      )

    cond do
      opts[:help] ->
        print_help()

      opts[:list_blueprints] ->
        list_blueprints()

      opts[:search] ->
        search_blueprints(opts[:search])

      true ->
        generate_mockups(opts)
    end
  end

  defp print_help do
    Mix.shell().info("""

    Printify Mockup Generator
    =========================

    Generates product mockups using the Printify API.

    Usage:
      mix generate_mockups [options]

    Options:
      --cleanup, -c       Delete created products from Printify after downloading mockups
      --search, -s TERM   Search for blueprints by name
      --list-blueprints   List all available blueprint IDs and names
      --help, -h          Show this help message

    Environment:
      PRINTIFY_API_TOKEN  Required. Your Printify API token.

    Examples:
      # Generate all mockups
      export PRINTIFY_API_TOKEN="your-token"
      mix generate_mockups

      # Generate and cleanup
      mix generate_mockups --cleanup

      # Find blueprint IDs
      mix generate_mockups --search "poster"
    """)
  end

  defp list_blueprints do
    Mix.shell().info("Fetching blueprints from Printify...")

    case MockupGenerator.list_blueprints() do
      blueprints when is_list(blueprints) ->
        Mix.shell().info("\nAvailable Blueprints:\n")

        blueprints
        |> Enum.each(fn {id, title} ->
          Mix.shell().info("  #{id}: #{title}")
        end)

        Mix.shell().info("\nTotal: #{length(blueprints)} blueprints")

      {:error, reason} ->
        Mix.shell().error("Error fetching blueprints: #{inspect(reason)}")
    end
  end

  defp search_blueprints(term) do
    Mix.shell().info("Searching for blueprints matching '#{term}'...")

    case MockupGenerator.search_blueprints(term) do
      results when is_list(results) ->
        if results == [] do
          Mix.shell().info("No blueprints found matching '#{term}'")
        else
          Mix.shell().info("\nMatching Blueprints:\n")

          results
          |> Enum.each(fn {id, title} ->
            Mix.shell().info("  #{id}: #{title}")
          end)

          Mix.shell().info("\nFound: #{length(results)} blueprints")
        end

      {:error, reason} ->
        Mix.shell().error("Error searching blueprints: #{inspect(reason)}")
    end
  end

  defp generate_mockups(opts) do
    cleanup = Keyword.get(opts, :cleanup, false)

    Mix.shell().info("""

    ╔═══════════════════════════════════════════╗
    ║     Printify Mockup Generator             ║
    ╠═══════════════════════════════════════════╣
    ║  Cleanup mode: #{if cleanup, do: "ON ", else: "OFF"}                        ║
    ╚═══════════════════════════════════════════╝

    """)

    # Verify API token is set
    case System.get_env("PRINTIFY_API_TOKEN") do
      nil ->
        Mix.shell().error("""
        Error: PRINTIFY_API_TOKEN environment variable is not set.

        To get your API token:
        1. Log in to Printify
        2. Go to Settings > API tokens
        3. Create a new token with required permissions

        Then run:
          export PRINTIFY_API_TOKEN="your-token"
          mix generate_mockups
        """)

      _token ->
        results = MockupGenerator.generate_all(cleanup: cleanup)

        # Summary
        successful = Enum.count(results, &match?({:ok, _, _, _}, &1))
        failed = Enum.count(results, &match?({:error, _, _}, &1))

        Mix.shell().info("""

        ═══════════════════════════════════════════
        Summary
        ═══════════════════════════════════════════
        Successful: #{successful}
        Failed: #{failed}
        ═══════════════════════════════════════════
        """)

        if failed > 0 do
          Mix.shell().error(
            "Some products failed to generate. Check the output above for details."
          )
        end
    end
  end
end
