defmodule Mix.Tasks.Operately.Gen.Notification.Items.Index do
  import Mix.Operately, only: [generate_file!: 2, list_files: 3, indent: 2]

  @path "assets/js/pages/NotificationsPage/NotificationItem"
  @pattern @path <> "/*.tsx"

  def run(_args) do
    types = list_files(@pattern, :basename, exclude: ["index"])

    generate_index(types)
  end

  def generate_index(types) do
    generate_file!("#{@path}/index.tsx", fn _path ->
      """
      //
      // Automatically generated with mix operate.gen.notification.items.index
      // Do not edit this file manually
      //

      import * as React from "react";

      #{import_types(types)}

      export default function NotificationItem({notification}) : JSX.Element | null {
        const activityType = notification.activity.content.__typename;

        switch (activityType) {
          #{indent(generate_cases(types), 4)}
          default:
            console.error("unhandled activity type, notification:", notification.id, "activity", notification.activity.id);
            return null;
        }
      }
      """
    end)
  end

  def import_types(types) do
    types
    |> Enum.map(fn type -> "import #{type} from \"./#{type}\"" end)
    |> Enum.join("\n")
  end

  def generate_cases(types) do
    Enum.map(types, fn type -> generate_case(type) end) |> Enum.join("\n")
  end

  def generate_case(type) do
    full_type_name = "ActivityContent" <> type

    """
    case \"#{full_type_name}\":
      return <#{type} notification={notification} />;
    """
  end

end
