DO $$
DECLARE
  column_type text;
BEGIN
  SELECT data_type
  INTO column_type
  FROM information_schema.columns
  WHERE table_schema = 'public'
    AND table_name = 'platform_models'
    AND column_name = 'model_type';

  IF column_type IS DISTINCT FROM 'jsonb' THEN
    DROP INDEX IF EXISTS idx_platform_models_lookup;
    ALTER TABLE platform_models
      DROP CONSTRAINT IF EXISTS platform_models_platform_id_model_name_model_type_key;

    ALTER TABLE platform_models
      ADD COLUMN IF NOT EXISTS model_type_next jsonb NOT NULL DEFAULT '[]'::jsonb;

    UPDATE platform_models
    SET model_type_next = CASE trim(model_type)
      WHEN 'chat' THEN '["text_generate"]'::jsonb
      WHEN 'text' THEN '["text_generate"]'::jsonb
      WHEN 'responses' THEN '["text_generate"]'::jsonb
      WHEN 'image' THEN '["image_generate","image_edit"]'::jsonb
      WHEN 'images.generations' THEN '["image_generate"]'::jsonb
      WHEN 'images.edits' THEN '["image_edit"]'::jsonb
      WHEN 'video' THEN '["video_generate"]'::jsonb
      WHEN 'videos.generations' THEN '["video_generate"]'::jsonb
      ELSE jsonb_build_array(trim(model_type))
    END;

    WITH ranked AS (
      SELECT id,
             first_value(id) OVER (
               PARTITION BY platform_id, model_name
               ORDER BY created_at ASC, id ASC
             ) AS keep_id,
             row_number() OVER (
               PARTITION BY platform_id, model_name
               ORDER BY created_at ASC, id ASC
             ) AS row_number
      FROM platform_models
    ),
    merged AS (
      SELECT ranked.keep_id,
             jsonb_agg(DISTINCT type_value ORDER BY type_value) AS model_type
      FROM ranked
      JOIN platform_models model_row ON model_row.id = ranked.id
      CROSS JOIN LATERAL jsonb_array_elements_text(model_row.model_type_next) AS type_item(type_value)
      GROUP BY ranked.keep_id
    )
    UPDATE platform_models target
    SET model_type_next = merged.model_type
    FROM merged
    WHERE target.id = merged.keep_id;

    WITH ranked AS (
      SELECT id,
             first_value(id) OVER (
               PARTITION BY platform_id, model_name
               ORDER BY created_at ASC, id ASC
             ) AS keep_id,
             row_number() OVER (
               PARTITION BY platform_id, model_name
               ORDER BY created_at ASC, id ASC
             ) AS row_number
      FROM platform_models
    )
    UPDATE gateway_access_rules rules
    SET resource_id = ranked.keep_id
    FROM ranked
    WHERE ranked.row_number > 1
      AND rules.resource_type = 'platform_model'
      AND rules.resource_id = ranked.id;

    WITH ranked AS (
      SELECT id,
             row_number() OVER (
               PARTITION BY platform_id, model_name
               ORDER BY created_at ASC, id ASC
             ) AS row_number
      FROM platform_models
    )
    DELETE FROM platform_models model_row
    USING ranked
    WHERE model_row.id = ranked.id
      AND ranked.row_number > 1;

    ALTER TABLE platform_models DROP COLUMN model_type;
    ALTER TABLE platform_models RENAME COLUMN model_type_next TO model_type;
  END IF;
END $$;

UPDATE platform_models
SET model_type = CASE
  WHEN jsonb_typeof(model_type) = 'array' THEN model_type
  WHEN jsonb_typeof(model_type) = 'string' THEN jsonb_build_array(model_type #>> '{}')
  ELSE '[]'::jsonb
END;

UPDATE platform_models
SET model_type = COALESCE((
  SELECT jsonb_agg(DISTINCT normalized_type ORDER BY normalized_type)
  FROM jsonb_array_elements_text(platform_models.model_type) AS item(model_type_value)
  CROSS JOIN LATERAL (
    VALUES
      (CASE item.model_type_value
        WHEN 'chat' THEN 'text_generate'
        WHEN 'text' THEN 'text_generate'
        WHEN 'responses' THEN 'text_generate'
        WHEN 'images.generations' THEN 'image_generate'
        WHEN 'images.edits' THEN 'image_edit'
        WHEN 'video' THEN 'video_generate'
        WHEN 'videos.generations' THEN 'video_generate'
        ELSE item.model_type_value
      END)
  ) AS normalized(normalized_type)
  WHERE trim(normalized_type) <> ''
), '[]'::jsonb);

UPDATE platform_models
SET model_type = '["image_generate","image_edit"]'::jsonb
WHERE model_type = '["image"]'::jsonb;

ALTER TABLE platform_models
  ALTER COLUMN model_type SET NOT NULL,
  ALTER COLUMN model_type SET DEFAULT '[]'::jsonb;

DROP INDEX IF EXISTS idx_platform_models_lookup;
CREATE INDEX IF NOT EXISTS idx_platform_models_lookup
  ON platform_models(model_name, enabled);

CREATE INDEX IF NOT EXISTS idx_platform_models_model_type
  ON platform_models USING gin(model_type);

CREATE UNIQUE INDEX IF NOT EXISTS idx_platform_models_platform_model_name
  ON platform_models(platform_id, model_name);
