using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using foodmarket.Infrastructure.Persistence;

#nullable disable

namespace foodmarket.Infrastructure.Persistence.Migrations
{
    /// <summary>Phase8d — UNIQUE индекс на (OrganizationId, Article) у products.
    ///
    /// Контроллер ProductsController.Create/Update УЖЕ ловит нарушение по
    /// имени индекса IX_products_OrganizationId_Article и возвращает 400
    /// «Артикул уже занят», но сам индекс был неуникальным — поэтому
    /// дубликаты артикулов проскакивали. Postgres NULL-значения индекс
    /// трактует как distinct по умолчанию: товары без Article можно
    /// держать без ограничения; пустая строка приравнена к одной — при
    /// необходимости несколько товаров без артикула пользователь оставляет
    /// поле NULL (UI присылает null, а не ""). Дубликаты existing — чистим
    /// в migration перед созданием индекса: дублям дописываем суффикс «-N».
    ///
    /// Идемпотентен (создание DROP+CREATE).</summary>
    [DbContext(typeof(AppDbContext))]
    [Migration("20260529100000_Phase8d_ProductArticleUnique")]
    public partial class Phase8d_ProductArticleUnique : Migration
    {
        protected override void Up(MigrationBuilder b)
        {
            b.Sql(@"
                -- Чистим существующие дубликаты article в рамках одной orgId.
                -- Сначала ловим (OrgId, Article) с count>1, потом нумеруем
                -- row_number'ом и дописываем -2/-3/... ко второму и далее.
                WITH dups AS (
                    SELECT
                        ""Id"",
                        ""Article"",
                        row_number() OVER (PARTITION BY ""OrganizationId"", ""Article"" ORDER BY ""CreatedAt"", ""Id"") AS rn
                    FROM public.products
                    WHERE ""Article"" IS NOT NULL AND ""Article"" <> ''
                )
                UPDATE public.products p
                SET ""Article"" = p.""Article"" || '-' || d.rn
                FROM dups d
                WHERE p.""Id"" = d.""Id"" AND d.rn > 1;

                -- Пересоздаём индекс уникальным. CREATE/DROP под IF EXISTS.
                DROP INDEX IF EXISTS public.""IX_products_OrganizationId_Article"";
                CREATE UNIQUE INDEX ""IX_products_OrganizationId_Article""
                    ON public.products (""OrganizationId"", ""Article"");
            ");
        }

        protected override void Down(MigrationBuilder b)
        {
            b.Sql(@"
                DROP INDEX IF EXISTS public.""IX_products_OrganizationId_Article"";
                CREATE INDEX ""IX_products_OrganizationId_Article""
                    ON public.products (""OrganizationId"", ""Article"");
            ");
        }
    }
}
