defmodule Tuesday.Repo.Migrations.CreateTables do
  @moduledoc """
  Updates resources based on their most recent snapshots.

  This file was autogenerated with `mix ash_postgres.generate_migrations`
  """

  use Ecto.Migration

  def up do
    create table(:users, primary_key: false) do
      add :id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true
      add :email, :citext, null: false

      add :inserted_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")

      add :updated_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")
    end

    create unique_index(:users, [:email], name: "users_unique_email_index")

    create table(:tasks, primary_key: false) do
      add :id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true
      add :title, :text, null: false
      add :description, :text
      add :is_done, :boolean, null: false, default: false
      add :priority, :bigint, null: false, default: 3
      add :story_point, :bigint, null: false, default: 3
      add :start_date, :date, default: fragment("CURRENT_DATE")
      add :due_date, :date

      add :inserted_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")

      add :updated_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")

      add :organization_id, :uuid
      add :project_id, :uuid, null: false
      add :parent_task_id, :uuid
    end

    create table(:task_assignee, primary_key: false) do
      add :id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true
      add :organization_member_id, :uuid

      add :inserted_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")

      add :updated_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")

      add :organization_id, :uuid
      add :task_id, :uuid, null: false
    end

    create table(:projects, primary_key: false) do
      add :id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true
      add :name, :text, null: false
      add :description, :text
      add :start_date, :date, null: false, default: fragment("CURRENT_DATE")
      add :end_date, :date
      add :status, :text, null: false, default: "active"

      add :inserted_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")

      add :updated_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")

      add :organization_id, :uuid, null: false
    end

    create table(:project_members, primary_key: false) do
      add :id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true
      add :project_role, :text, null: false, default: "standard"

      add :inserted_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")

      add :updated_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")

      add :organization_id, :uuid
      add :organization_member_id, :uuid, null: false
      add :project_id, :uuid, null: false
    end

    create table(:posts, primary_key: false) do
      add :id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true
      add :title, :text, null: false
    end

    create table(:organizations, primary_key: false) do
      add :id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true
    end

    alter table(:tasks) do
      modify :organization_id,
             references(:organizations,
               column: :id,
               name: "tasks_organization_id_fkey",
               type: :uuid,
               prefix: "public"
             )

      modify :project_id,
             references(:projects,
               column: :id,
               name: "tasks_project_id_fkey",
               type: :uuid,
               prefix: "public"
             )

      modify :parent_task_id,
             references(:tasks,
               column: :id,
               name: "tasks_parent_task_id_fkey",
               type: :uuid,
               prefix: "public"
             )
    end

    create unique_index(:tasks, [:organization_id, :title, :project_id],
             name: "tasks_unique_title_per_project_index"
           )

    alter table(:projects) do
      modify :organization_id,
             references(:organizations,
               column: :id,
               name: "projects_organization_id_fkey",
               type: :uuid,
               prefix: "public"
             )
    end

    create unique_index(:projects, [:organization_id, :name, :organization_id],
             name: "projects_unique_name_per_organization_index"
           )

    alter table(:project_members) do
      modify :organization_id,
             references(:organizations,
               column: :id,
               name: "project_members_organization_id_fkey",
               type: :uuid,
               prefix: "public"
             )
    end

    alter table(:organizations) do
      add :name, :text, null: false
      add :slug, :text
      add :plan_type, :text, null: false, default: "free"
      add :can_standard_member_create_project, :boolean, default: true

      add :inserted_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")

      add :updated_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")
    end

    create unique_index(:organizations, [:name], name: "organizations_unique_name_index")

    create table(:organization_members, primary_key: false) do
      add :id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true
    end

    alter table(:task_assignee) do
      modify :organization_member_id,
             references(:organization_members,
               column: :id,
               name: "task_assignee_organization_member_id_fkey",
               type: :uuid,
               prefix: "public"
             )

      modify :organization_id,
             references(:organizations,
               column: :id,
               name: "task_assignee_organization_id_fkey",
               type: :uuid,
               prefix: "public"
             )

      modify :task_id,
             references(:tasks,
               column: :id,
               name: "task_assignee_task_id_fkey",
               type: :uuid,
               prefix: "public"
             )
    end

    alter table(:project_members) do
      modify :organization_member_id,
             references(:organization_members,
               column: :id,
               name: "project_members_organization_member_id_fkey",
               type: :uuid,
               prefix: "public"
             )

      modify :project_id,
             references(:projects,
               column: :id,
               name: "project_members_project_id_fkey",
               type: :uuid,
               prefix: "public"
             )
    end

    create unique_index(
             :project_members,
             [:organization_id, :organization_member_id, :project_id],
             name: "project_members_unique_membership_index"
           )

    alter table(:organization_members) do
      add :username, :text, null: false
      add :role, :text, null: false, default: "standard"
      add :status, :text, null: false, default: "active"

      add :inserted_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")

      add :updated_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")

      add :user_id,
          references(:users,
            column: :id,
            name: "organization_members_user_id_fkey",
            type: :uuid,
            prefix: "public"
          ),
          null: false

      add :organization_id,
          references(:organizations,
            column: :id,
            name: "organization_members_organization_id_fkey",
            type: :uuid,
            prefix: "public"
          ),
          null: false
    end

    create table(:comments, primary_key: false) do
      add :id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true
      add :body, :text, null: false

      add :organization_member_id,
          references(:organization_members,
            column: :id,
            name: "comments_organization_member_id_fkey",
            type: :uuid,
            prefix: "public"
          )

      add :inserted_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")

      add :updated_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")

      add :organization_id,
          references(:organizations,
            column: :id,
            name: "comments_organization_id_fkey",
            type: :uuid,
            prefix: "public"
          )

      add :task_id,
          references(:tasks,
            column: :id,
            name: "comments_task_id_fkey",
            type: :uuid,
            prefix: "public"
          ),
          null: false
    end

    create table(:activity_logs, primary_key: false) do
      add :id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true
      add :action, :text, null: false
      add :target, :text, null: false
      add :status, :text, null: false, default: "success"
      add :metadata, :map, default: %{}

      add :organization_member_id,
          references(:organization_members,
            column: :id,
            name: "activity_logs_organization_member_id_fkey",
            type: :uuid,
            prefix: "public"
          )

      add :occurred_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")

      add :organization_id,
          references(:organizations,
            column: :id,
            name: "activity_logs_organization_id_fkey",
            type: :uuid,
            prefix: "public"
          ),
          null: false
    end
  end

  def down do
    drop constraint(:activity_logs, "activity_logs_organization_member_id_fkey")

    drop constraint(:activity_logs, "activity_logs_organization_id_fkey")

    drop table(:activity_logs)

    drop constraint(:comments, "comments_organization_member_id_fkey")

    drop constraint(:comments, "comments_organization_id_fkey")

    drop constraint(:comments, "comments_task_id_fkey")

    drop table(:comments)

    drop constraint(:organization_members, "organization_members_user_id_fkey")

    drop constraint(:organization_members, "organization_members_organization_id_fkey")

    alter table(:organization_members) do
      remove :organization_id
      remove :user_id
      remove :updated_at
      remove :inserted_at
      remove :status
      remove :role
      remove :username
    end

    drop_if_exists unique_index(
                     :project_members,
                     [:organization_id, :organization_member_id, :project_id],
                     name: "project_members_unique_membership_index"
                   )

    drop constraint(:project_members, "project_members_organization_member_id_fkey")

    drop constraint(:project_members, "project_members_project_id_fkey")

    alter table(:project_members) do
      modify :project_id, :uuid
      modify :organization_member_id, :uuid
    end

    drop constraint(:task_assignee, "task_assignee_organization_member_id_fkey")

    drop constraint(:task_assignee, "task_assignee_organization_id_fkey")

    drop constraint(:task_assignee, "task_assignee_task_id_fkey")

    alter table(:task_assignee) do
      modify :task_id, :uuid
      modify :organization_id, :uuid
      modify :organization_member_id, :uuid
    end

    drop table(:organization_members)

    drop_if_exists unique_index(:organizations, [:name], name: "organizations_unique_name_index")

    alter table(:organizations) do
      remove :updated_at
      remove :inserted_at
      remove :can_standard_member_create_project
      remove :plan_type
      remove :slug
      remove :name
    end

    drop constraint(:project_members, "project_members_organization_id_fkey")

    alter table(:project_members) do
      modify :organization_id, :uuid
    end

    drop_if_exists unique_index(:projects, [:organization_id, :name, :organization_id],
                     name: "projects_unique_name_per_organization_index"
                   )

    drop constraint(:projects, "projects_organization_id_fkey")

    alter table(:projects) do
      modify :organization_id, :uuid
    end

    drop_if_exists unique_index(:tasks, [:organization_id, :title, :project_id],
                     name: "tasks_unique_title_per_project_index"
                   )

    drop constraint(:tasks, "tasks_organization_id_fkey")

    drop constraint(:tasks, "tasks_project_id_fkey")

    drop constraint(:tasks, "tasks_parent_task_id_fkey")

    alter table(:tasks) do
      modify :parent_task_id, :uuid
      modify :project_id, :uuid
      modify :organization_id, :uuid
    end

    drop table(:organizations)

    drop table(:posts)

    drop table(:project_members)

    drop table(:projects)

    drop table(:task_assignee)

    drop table(:tasks)

    drop_if_exists unique_index(:users, [:email], name: "users_unique_email_index")

    drop table(:users)
  end
end
