import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'

export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
  await db.execute(sql`
   CREATE TYPE "public"."enum_users_roles" AS ENUM('super-admin', 'user');
  CREATE TYPE "public"."enum_users_tenants_roles" AS ENUM('admin', 'caregiver', 'kitchen');
  CREATE TYPE "public"."enum_meal_orders_meal_type" AS ENUM('breakfast', 'lunch', 'dinner');
  CREATE TYPE "public"."enum_meal_orders_status" AS ENUM('draft', 'submitted', 'preparing', 'completed');
  CREATE TYPE "public"."enum_meals_meal_type" AS ENUM('breakfast', 'lunch', 'dinner');
  CREATE TYPE "public"."enum_meals_status" AS ENUM('pending', 'preparing', 'prepared');
  CREATE TYPE "public"."enum_meals_lunch_portion_size" AS ENUM('small', 'large', 'vegetarian');
  CREATE TABLE "users_roles" (
  	"order" integer NOT NULL,
  	"parent_id" integer NOT NULL,
  	"value" "enum_users_roles",
  	"id" serial PRIMARY KEY NOT NULL
  );
  
  CREATE TABLE "users_tenants_roles" (
  	"order" integer NOT NULL,
  	"parent_id" varchar NOT NULL,
  	"value" "enum_users_tenants_roles",
  	"id" serial PRIMARY KEY NOT NULL
  );
  
  CREATE TABLE "users_tenants" (
  	"_order" integer NOT NULL,
  	"_parent_id" integer NOT NULL,
  	"id" varchar PRIMARY KEY NOT NULL,
  	"tenant_id" integer NOT NULL
  );
  
  CREATE TABLE "users_sessions" (
  	"_order" integer NOT NULL,
  	"_parent_id" integer NOT NULL,
  	"id" varchar PRIMARY KEY NOT NULL,
  	"created_at" timestamp(3) with time zone,
  	"expires_at" timestamp(3) with time zone NOT NULL
  );
  
  CREATE TABLE "users" (
  	"id" serial PRIMARY KEY NOT NULL,
  	"name" varchar,
  	"password" varchar,
  	"username" varchar,
  	"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
  	"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
  	"email" varchar NOT NULL,
  	"reset_password_token" varchar,
  	"reset_password_expiration" timestamp(3) with time zone,
  	"salt" varchar,
  	"hash" varchar,
  	"login_attempts" numeric DEFAULT 0,
  	"lock_until" timestamp(3) with time zone
  );
  
  CREATE TABLE "tenants" (
  	"id" serial PRIMARY KEY NOT NULL,
  	"name" varchar NOT NULL,
  	"slug" varchar NOT NULL,
  	"domain" varchar,
  	"address" varchar,
  	"phone" varchar,
  	"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
  	"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
  );
  
  CREATE TABLE "residents" (
  	"id" serial PRIMARY KEY NOT NULL,
  	"tenant_id" integer,
  	"name" varchar NOT NULL,
  	"room" varchar NOT NULL,
  	"table" varchar,
  	"station" varchar,
  	"high_caloric" boolean DEFAULT false,
  	"active" boolean DEFAULT true,
  	"aversions" varchar,
  	"notes" varchar,
  	"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
  	"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
  );
  
  CREATE TABLE "meal_orders" (
  	"id" serial PRIMARY KEY NOT NULL,
  	"tenant_id" integer,
  	"title" varchar,
  	"date" timestamp(3) with time zone NOT NULL,
  	"meal_type" "enum_meal_orders_meal_type" NOT NULL,
  	"status" "enum_meal_orders_status" DEFAULT 'draft' NOT NULL,
  	"meal_count" numeric DEFAULT 0,
  	"submitted_at" timestamp(3) with time zone,
  	"created_by_id" integer,
  	"notes" varchar,
  	"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
  	"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
  );
  
  CREATE TABLE "meals" (
  	"id" serial PRIMARY KEY NOT NULL,
  	"tenant_id" integer,
  	"title" varchar,
  	"order_id" integer,
  	"resident_id" integer NOT NULL,
  	"date" timestamp(3) with time zone NOT NULL,
  	"meal_type" "enum_meals_meal_type" NOT NULL,
  	"status" "enum_meals_status" DEFAULT 'pending' NOT NULL,
  	"form_image_id" integer,
  	"created_by_id" integer,
  	"high_caloric" boolean DEFAULT false,
  	"aversions" varchar,
  	"notes" varchar,
  	"breakfast_according_to_plan" boolean DEFAULT false,
  	"breakfast_bread_bread_roll" boolean,
  	"breakfast_bread_whole_grain_roll" boolean,
  	"breakfast_bread_grey_bread" boolean,
  	"breakfast_bread_whole_grain_bread" boolean,
  	"breakfast_bread_white_bread" boolean,
  	"breakfast_bread_crispbread" boolean,
  	"breakfast_porridge" boolean,
  	"breakfast_preparation_sliced" boolean,
  	"breakfast_preparation_spread" boolean,
  	"breakfast_spreads_butter" boolean,
  	"breakfast_spreads_margarine" boolean,
  	"breakfast_spreads_jam" boolean,
  	"breakfast_spreads_diabetic_jam" boolean,
  	"breakfast_spreads_honey" boolean,
  	"breakfast_spreads_cheese" boolean,
  	"breakfast_spreads_quark" boolean,
  	"breakfast_spreads_sausage" boolean,
  	"breakfast_beverages_coffee" boolean,
  	"breakfast_beverages_tea" boolean,
  	"breakfast_beverages_hot_milk" boolean,
  	"breakfast_beverages_cold_milk" boolean,
  	"breakfast_additions_sugar" boolean,
  	"breakfast_additions_sweetener" boolean,
  	"breakfast_additions_coffee_creamer" boolean,
  	"lunch_portion_size" "enum_meals_lunch_portion_size",
  	"lunch_soup" boolean,
  	"lunch_dessert" boolean,
  	"lunch_special_preparations_pureed_food" boolean,
  	"lunch_special_preparations_pureed_meat" boolean,
  	"lunch_special_preparations_sliced_meat" boolean,
  	"lunch_special_preparations_mashed_potatoes" boolean,
  	"lunch_restrictions_no_fish" boolean,
  	"lunch_restrictions_finger_food" boolean,
  	"lunch_restrictions_only_sweet" boolean,
  	"dinner_according_to_plan" boolean DEFAULT false,
  	"dinner_bread_grey_bread" boolean,
  	"dinner_bread_whole_grain_bread" boolean,
  	"dinner_bread_white_bread" boolean,
  	"dinner_bread_crispbread" boolean,
  	"dinner_preparation_spread" boolean,
  	"dinner_preparation_sliced" boolean,
  	"dinner_spreads_butter" boolean,
  	"dinner_spreads_margarine" boolean,
  	"dinner_soup" boolean,
  	"dinner_porridge" boolean,
  	"dinner_no_fish" boolean,
  	"dinner_beverages_tea" boolean,
  	"dinner_beverages_cocoa" boolean,
  	"dinner_beverages_hot_milk" boolean,
  	"dinner_beverages_cold_milk" boolean,
  	"dinner_additions_sugar" boolean,
  	"dinner_additions_sweetener" boolean,
  	"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
  	"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
  );
  
  CREATE TABLE "media" (
  	"id" serial PRIMARY KEY NOT NULL,
  	"alt" varchar,
  	"caption" varchar,
  	"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
  	"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
  	"url" varchar,
  	"thumbnail_u_r_l" varchar,
  	"filename" varchar,
  	"mime_type" varchar,
  	"filesize" numeric,
  	"width" numeric,
  	"height" numeric,
  	"focal_x" numeric,
  	"focal_y" numeric,
  	"sizes_thumbnail_url" varchar,
  	"sizes_thumbnail_width" numeric,
  	"sizes_thumbnail_height" numeric,
  	"sizes_thumbnail_mime_type" varchar,
  	"sizes_thumbnail_filesize" numeric,
  	"sizes_thumbnail_filename" varchar,
  	"sizes_preview_url" varchar,
  	"sizes_preview_width" numeric,
  	"sizes_preview_height" numeric,
  	"sizes_preview_mime_type" varchar,
  	"sizes_preview_filesize" numeric,
  	"sizes_preview_filename" varchar
  );
  
  CREATE TABLE "payload_kv" (
  	"id" serial PRIMARY KEY NOT NULL,
  	"key" varchar NOT NULL,
  	"data" jsonb NOT NULL
  );
  
  CREATE TABLE "payload_locked_documents" (
  	"id" serial PRIMARY KEY NOT NULL,
  	"global_slug" varchar,
  	"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
  	"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
  );
  
  CREATE TABLE "payload_locked_documents_rels" (
  	"id" serial PRIMARY KEY NOT NULL,
  	"order" integer,
  	"parent_id" integer NOT NULL,
  	"path" varchar NOT NULL,
  	"users_id" integer,
  	"tenants_id" integer,
  	"residents_id" integer,
  	"meal_orders_id" integer,
  	"meals_id" integer,
  	"media_id" integer
  );
  
  CREATE TABLE "payload_preferences" (
  	"id" serial PRIMARY KEY NOT NULL,
  	"key" varchar,
  	"value" jsonb,
  	"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
  	"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
  );
  
  CREATE TABLE "payload_preferences_rels" (
  	"id" serial PRIMARY KEY NOT NULL,
  	"order" integer,
  	"parent_id" integer NOT NULL,
  	"path" varchar NOT NULL,
  	"users_id" integer
  );
  
  CREATE TABLE "payload_migrations" (
  	"id" serial PRIMARY KEY NOT NULL,
  	"name" varchar,
  	"batch" numeric,
  	"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
  	"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
  );
  
  ALTER TABLE "users_roles" ADD CONSTRAINT "users_roles_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
  ALTER TABLE "users_tenants_roles" ADD CONSTRAINT "users_tenants_roles_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."users_tenants"("id") ON DELETE cascade ON UPDATE no action;
  ALTER TABLE "users_tenants" ADD CONSTRAINT "users_tenants_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;
  ALTER TABLE "users_tenants" ADD CONSTRAINT "users_tenants_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
  ALTER TABLE "users_sessions" ADD CONSTRAINT "users_sessions_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
  ALTER TABLE "residents" ADD CONSTRAINT "residents_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;
  ALTER TABLE "meal_orders" ADD CONSTRAINT "meal_orders_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;
  ALTER TABLE "meal_orders" ADD CONSTRAINT "meal_orders_created_by_id_users_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
  ALTER TABLE "meals" ADD CONSTRAINT "meals_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;
  ALTER TABLE "meals" ADD CONSTRAINT "meals_order_id_meal_orders_id_fk" FOREIGN KEY ("order_id") REFERENCES "public"."meal_orders"("id") ON DELETE set null ON UPDATE no action;
  ALTER TABLE "meals" ADD CONSTRAINT "meals_resident_id_residents_id_fk" FOREIGN KEY ("resident_id") REFERENCES "public"."residents"("id") ON DELETE set null ON UPDATE no action;
  ALTER TABLE "meals" ADD CONSTRAINT "meals_form_image_id_media_id_fk" FOREIGN KEY ("form_image_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
  ALTER TABLE "meals" ADD CONSTRAINT "meals_created_by_id_users_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
  ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."payload_locked_documents"("id") ON DELETE cascade ON UPDATE no action;
  ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_users_fk" FOREIGN KEY ("users_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
  ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_tenants_fk" FOREIGN KEY ("tenants_id") REFERENCES "public"."tenants"("id") ON DELETE cascade ON UPDATE no action;
  ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_residents_fk" FOREIGN KEY ("residents_id") REFERENCES "public"."residents"("id") ON DELETE cascade ON UPDATE no action;
  ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_meal_orders_fk" FOREIGN KEY ("meal_orders_id") REFERENCES "public"."meal_orders"("id") ON DELETE cascade ON UPDATE no action;
  ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_meals_fk" FOREIGN KEY ("meals_id") REFERENCES "public"."meals"("id") ON DELETE cascade ON UPDATE no action;
  ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_media_fk" FOREIGN KEY ("media_id") REFERENCES "public"."media"("id") ON DELETE cascade ON UPDATE no action;
  ALTER TABLE "payload_preferences_rels" ADD CONSTRAINT "payload_preferences_rels_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."payload_preferences"("id") ON DELETE cascade ON UPDATE no action;
  ALTER TABLE "payload_preferences_rels" ADD CONSTRAINT "payload_preferences_rels_users_fk" FOREIGN KEY ("users_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
  CREATE INDEX "users_roles_order_idx" ON "users_roles" USING btree ("order");
  CREATE INDEX "users_roles_parent_idx" ON "users_roles" USING btree ("parent_id");
  CREATE INDEX "users_tenants_roles_order_idx" ON "users_tenants_roles" USING btree ("order");
  CREATE INDEX "users_tenants_roles_parent_idx" ON "users_tenants_roles" USING btree ("parent_id");
  CREATE INDEX "users_tenants_order_idx" ON "users_tenants" USING btree ("_order");
  CREATE INDEX "users_tenants_parent_id_idx" ON "users_tenants" USING btree ("_parent_id");
  CREATE INDEX "users_tenants_tenant_idx" ON "users_tenants" USING btree ("tenant_id");
  CREATE INDEX "users_sessions_order_idx" ON "users_sessions" USING btree ("_order");
  CREATE INDEX "users_sessions_parent_id_idx" ON "users_sessions" USING btree ("_parent_id");
  CREATE INDEX "users_username_idx" ON "users" USING btree ("username");
  CREATE INDEX "users_updated_at_idx" ON "users" USING btree ("updated_at");
  CREATE INDEX "users_created_at_idx" ON "users" USING btree ("created_at");
  CREATE UNIQUE INDEX "users_email_idx" ON "users" USING btree ("email");
  CREATE UNIQUE INDEX "tenants_slug_idx" ON "tenants" USING btree ("slug");
  CREATE INDEX "tenants_updated_at_idx" ON "tenants" USING btree ("updated_at");
  CREATE INDEX "tenants_created_at_idx" ON "tenants" USING btree ("created_at");
  CREATE INDEX "residents_tenant_idx" ON "residents" USING btree ("tenant_id");
  CREATE INDEX "residents_room_idx" ON "residents" USING btree ("room");
  CREATE INDEX "residents_updated_at_idx" ON "residents" USING btree ("updated_at");
  CREATE INDEX "residents_created_at_idx" ON "residents" USING btree ("created_at");
  CREATE INDEX "meal_orders_tenant_idx" ON "meal_orders" USING btree ("tenant_id");
  CREATE INDEX "meal_orders_date_idx" ON "meal_orders" USING btree ("date");
  CREATE INDEX "meal_orders_meal_type_idx" ON "meal_orders" USING btree ("meal_type");
  CREATE INDEX "meal_orders_status_idx" ON "meal_orders" USING btree ("status");
  CREATE INDEX "meal_orders_created_by_idx" ON "meal_orders" USING btree ("created_by_id");
  CREATE INDEX "meal_orders_updated_at_idx" ON "meal_orders" USING btree ("updated_at");
  CREATE INDEX "meal_orders_created_at_idx" ON "meal_orders" USING btree ("created_at");
  CREATE INDEX "meals_tenant_idx" ON "meals" USING btree ("tenant_id");
  CREATE INDEX "meals_order_idx" ON "meals" USING btree ("order_id");
  CREATE INDEX "meals_resident_idx" ON "meals" USING btree ("resident_id");
  CREATE INDEX "meals_date_idx" ON "meals" USING btree ("date");
  CREATE INDEX "meals_meal_type_idx" ON "meals" USING btree ("meal_type");
  CREATE INDEX "meals_status_idx" ON "meals" USING btree ("status");
  CREATE INDEX "meals_form_image_idx" ON "meals" USING btree ("form_image_id");
  CREATE INDEX "meals_created_by_idx" ON "meals" USING btree ("created_by_id");
  CREATE INDEX "meals_updated_at_idx" ON "meals" USING btree ("updated_at");
  CREATE INDEX "meals_created_at_idx" ON "meals" USING btree ("created_at");
  CREATE INDEX "media_updated_at_idx" ON "media" USING btree ("updated_at");
  CREATE INDEX "media_created_at_idx" ON "media" USING btree ("created_at");
  CREATE UNIQUE INDEX "media_filename_idx" ON "media" USING btree ("filename");
  CREATE INDEX "media_sizes_thumbnail_sizes_thumbnail_filename_idx" ON "media" USING btree ("sizes_thumbnail_filename");
  CREATE INDEX "media_sizes_preview_sizes_preview_filename_idx" ON "media" USING btree ("sizes_preview_filename");
  CREATE UNIQUE INDEX "payload_kv_key_idx" ON "payload_kv" USING btree ("key");
  CREATE INDEX "payload_locked_documents_global_slug_idx" ON "payload_locked_documents" USING btree ("global_slug");
  CREATE INDEX "payload_locked_documents_updated_at_idx" ON "payload_locked_documents" USING btree ("updated_at");
  CREATE INDEX "payload_locked_documents_created_at_idx" ON "payload_locked_documents" USING btree ("created_at");
  CREATE INDEX "payload_locked_documents_rels_order_idx" ON "payload_locked_documents_rels" USING btree ("order");
  CREATE INDEX "payload_locked_documents_rels_parent_idx" ON "payload_locked_documents_rels" USING btree ("parent_id");
  CREATE INDEX "payload_locked_documents_rels_path_idx" ON "payload_locked_documents_rels" USING btree ("path");
  CREATE INDEX "payload_locked_documents_rels_users_id_idx" ON "payload_locked_documents_rels" USING btree ("users_id");
  CREATE INDEX "payload_locked_documents_rels_tenants_id_idx" ON "payload_locked_documents_rels" USING btree ("tenants_id");
  CREATE INDEX "payload_locked_documents_rels_residents_id_idx" ON "payload_locked_documents_rels" USING btree ("residents_id");
  CREATE INDEX "payload_locked_documents_rels_meal_orders_id_idx" ON "payload_locked_documents_rels" USING btree ("meal_orders_id");
  CREATE INDEX "payload_locked_documents_rels_meals_id_idx" ON "payload_locked_documents_rels" USING btree ("meals_id");
  CREATE INDEX "payload_locked_documents_rels_media_id_idx" ON "payload_locked_documents_rels" USING btree ("media_id");
  CREATE INDEX "payload_preferences_key_idx" ON "payload_preferences" USING btree ("key");
  CREATE INDEX "payload_preferences_updated_at_idx" ON "payload_preferences" USING btree ("updated_at");
  CREATE INDEX "payload_preferences_created_at_idx" ON "payload_preferences" USING btree ("created_at");
  CREATE INDEX "payload_preferences_rels_order_idx" ON "payload_preferences_rels" USING btree ("order");
  CREATE INDEX "payload_preferences_rels_parent_idx" ON "payload_preferences_rels" USING btree ("parent_id");
  CREATE INDEX "payload_preferences_rels_path_idx" ON "payload_preferences_rels" USING btree ("path");
  CREATE INDEX "payload_preferences_rels_users_id_idx" ON "payload_preferences_rels" USING btree ("users_id");
  CREATE INDEX "payload_migrations_updated_at_idx" ON "payload_migrations" USING btree ("updated_at");
  CREATE INDEX "payload_migrations_created_at_idx" ON "payload_migrations" USING btree ("created_at");`)
}

export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
  await db.execute(sql`
   DROP TABLE "users_roles" CASCADE;
  DROP TABLE "users_tenants_roles" CASCADE;
  DROP TABLE "users_tenants" CASCADE;
  DROP TABLE "users_sessions" CASCADE;
  DROP TABLE "users" CASCADE;
  DROP TABLE "tenants" CASCADE;
  DROP TABLE "residents" CASCADE;
  DROP TABLE "meal_orders" CASCADE;
  DROP TABLE "meals" CASCADE;
  DROP TABLE "media" CASCADE;
  DROP TABLE "payload_kv" CASCADE;
  DROP TABLE "payload_locked_documents" CASCADE;
  DROP TABLE "payload_locked_documents_rels" CASCADE;
  DROP TABLE "payload_preferences" CASCADE;
  DROP TABLE "payload_preferences_rels" CASCADE;
  DROP TABLE "payload_migrations" CASCADE;
  DROP TYPE "public"."enum_users_roles";
  DROP TYPE "public"."enum_users_tenants_roles";
  DROP TYPE "public"."enum_meal_orders_meal_type";
  DROP TYPE "public"."enum_meal_orders_status";
  DROP TYPE "public"."enum_meals_meal_type";
  DROP TYPE "public"."enum_meals_status";
  DROP TYPE "public"."enum_meals_lunch_portion_size";`)
}
