BEGIN;

UPDATE "holiday_calendars"
SET "stateCode" = UPPER("stateCode")
WHERE "stateCode" IS NOT NULL;

UPDATE "holiday_calendars"
SET "stateCode" = NULL,
    "metroCityId" = NULL
WHERE "scopeType" = 'COUNTRY';

UPDATE "holiday_calendars"
SET "metroCityId" = NULL
WHERE "scopeType" = 'STATE';

CREATE TEMP TABLE "tmp_holiday_calendar_merge_map" (
  "duplicate_id" TEXT PRIMARY KEY,
  "keeper_id" TEXT NOT NULL
) ON COMMIT DROP;

WITH ranked AS (
  SELECT
    "id",
    FIRST_VALUE("id") OVER (
      PARTITION BY "countryId"
      ORDER BY "priority" DESC, "createdAt" DESC, "id" DESC
    ) AS "keeper_id",
    ROW_NUMBER() OVER (
      PARTITION BY "countryId"
      ORDER BY "priority" DESC, "createdAt" DESC, "id" DESC
    ) AS "rn"
  FROM "holiday_calendars"
  WHERE "scopeType" = 'COUNTRY'
)
INSERT INTO "tmp_holiday_calendar_merge_map" ("duplicate_id", "keeper_id")
SELECT "id", "keeper_id"
FROM ranked
WHERE "rn" > 1;

WITH ranked AS (
  SELECT
    "id",
    FIRST_VALUE("id") OVER (
      PARTITION BY "countryId", "stateCode"
      ORDER BY "priority" DESC, "createdAt" DESC, "id" DESC
    ) AS "keeper_id",
    ROW_NUMBER() OVER (
      PARTITION BY "countryId", "stateCode"
      ORDER BY "priority" DESC, "createdAt" DESC, "id" DESC
    ) AS "rn"
  FROM "holiday_calendars"
  WHERE "scopeType" = 'STATE'
    AND "stateCode" IS NOT NULL
)
INSERT INTO "tmp_holiday_calendar_merge_map" ("duplicate_id", "keeper_id")
SELECT "id", "keeper_id"
FROM ranked
WHERE "rn" > 1
ON CONFLICT ("duplicate_id") DO NOTHING;

WITH ranked AS (
  SELECT
    "id",
    FIRST_VALUE("id") OVER (
      PARTITION BY "countryId", "metroCityId"
      ORDER BY "priority" DESC, "createdAt" DESC, "id" DESC
    ) AS "keeper_id",
    ROW_NUMBER() OVER (
      PARTITION BY "countryId", "metroCityId"
      ORDER BY "priority" DESC, "createdAt" DESC, "id" DESC
    ) AS "rn"
  FROM "holiday_calendars"
  WHERE "scopeType" = 'CITY'
    AND "metroCityId" IS NOT NULL
)
INSERT INTO "tmp_holiday_calendar_merge_map" ("duplicate_id", "keeper_id")
SELECT "id", "keeper_id"
FROM ranked
WHERE "rn" > 1
ON CONFLICT ("duplicate_id") DO NOTHING;

UPDATE "holiday_calendar_entries" AS "entry"
SET "holidayCalendarId" = "map"."keeper_id"
FROM "tmp_holiday_calendar_merge_map" AS "map"
WHERE "entry"."holidayCalendarId" = "map"."duplicate_id"
  AND NOT EXISTS (
    SELECT 1
    FROM "holiday_calendar_entries" AS "existing"
    WHERE "existing"."holidayCalendarId" = "map"."keeper_id"
      AND "existing"."date" = "entry"."date"
  );

WITH ranked_entries AS (
  SELECT
    "id",
    ROW_NUMBER() OVER (
      PARTITION BY "holidayCalendarId", "date"
      ORDER BY "isRecurringAnnual" DESC, "updatedAt" DESC, "createdAt" DESC, "id" DESC
    ) AS "rn"
  FROM "holiday_calendar_entries"
)
DELETE FROM "holiday_calendar_entries" AS "entry"
USING ranked_entries
WHERE "entry"."id" = ranked_entries."id"
  AND ranked_entries."rn" > 1;

DELETE FROM "holiday_calendars" AS "calendar"
USING "tmp_holiday_calendar_merge_map" AS "map"
WHERE "calendar"."id" = "map"."duplicate_id";

DROP INDEX IF EXISTS "holiday_calendar_entries_holidayCalendarId_date_name_key";
DROP INDEX IF EXISTS "holiday_calendar_entries_holidayCalendarId_date_key";
CREATE UNIQUE INDEX "holiday_calendar_entries_holidayCalendarId_date_key"
  ON "holiday_calendar_entries" ("holidayCalendarId", "date");

ALTER TABLE "holiday_calendars"
  DROP CONSTRAINT IF EXISTS "holiday_calendars_scope_fields_check";

ALTER TABLE "holiday_calendars"
  ADD CONSTRAINT "holiday_calendars_scope_fields_check"
  CHECK (
    ("scopeType" = 'COUNTRY' AND "stateCode" IS NULL AND "metroCityId" IS NULL)
    OR ("scopeType" = 'STATE' AND "stateCode" IS NOT NULL AND "metroCityId" IS NULL)
    OR ("scopeType" = 'CITY' AND "metroCityId" IS NOT NULL)
  );

DROP INDEX IF EXISTS "holiday_calendars_country_scope_unique";
DROP INDEX IF EXISTS "holiday_calendars_state_scope_unique";
DROP INDEX IF EXISTS "holiday_calendars_city_scope_unique";

CREATE UNIQUE INDEX "holiday_calendars_country_scope_unique"
  ON "holiday_calendars" ("countryId")
  WHERE "scopeType" = 'COUNTRY';

CREATE UNIQUE INDEX "holiday_calendars_state_scope_unique"
  ON "holiday_calendars" ("countryId", "stateCode")
  WHERE "scopeType" = 'STATE' AND "stateCode" IS NOT NULL;

CREATE UNIQUE INDEX "holiday_calendars_city_scope_unique"
  ON "holiday_calendars" ("countryId", "metroCityId")
  WHERE "scopeType" = 'CITY' AND "metroCityId" IS NOT NULL;

COMMIT;
