using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
{
    /// <summary>
    /// SMS Notifications: makes a notification recipient's contact path optional and adds
    /// the central SMS-provider (Twilio) configuration table.
    ///
    /// 1. <c>NotificationRecipients.EmailAddress</c> becomes nullable — an SMS-only recipient
    ///    carries a <c>PhoneNumber</c> and no email. (ALTER COLUMN, naturally idempotent.)
    /// 2. <c>NotificationRecipients.PhoneNumber nvarchar(32) NULL</c> — E.164 phone for SMS
    ///    recipients (guarded ADD).
    /// 3. <c>SmsConfigurations</c> table — central-only provider config; <c>AuthToken</c> is
    ///    stored encrypted at rest (EncryptedStringConverter → <c>nvarchar(max)</c>, mirroring
    ///    <c>SmtpConfigurations.Credentials</c>) (guarded CREATE TABLE).
    ///
    /// Every DDL statement is guarded so the migration is safe to re-run against a
    /// partially-migrated database (the repo's idempotent-migration convention; see
    /// AddListAttributeElementType).
    /// </summary>
    public partial class AddSmsNotifications : Migration
    {
        /// <inheritdoc />
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            // ALTER COLUMN is naturally idempotent: re-running re-applies the same nullable shape.
            migrationBuilder.Sql("ALTER TABLE [NotificationRecipients] ALTER COLUMN [EmailAddress] nvarchar(500) NULL;");

            migrationBuilder.Sql(@"
IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE Name='PhoneNumber' AND Object_ID=Object_ID('NotificationRecipients'))
    ALTER TABLE [NotificationRecipients] ADD [PhoneNumber] nvarchar(32) NULL;");

            migrationBuilder.Sql(@"
IF OBJECT_ID(N'dbo.SmsConfigurations', N'U') IS NULL
    CREATE TABLE [SmsConfigurations] (
        [Id] int NOT NULL IDENTITY(1, 1),
        [AccountSid] nvarchar(100) NOT NULL,
        [AuthToken] nvarchar(max) NULL,
        [FromNumber] nvarchar(32) NOT NULL,
        [MessagingServiceSid] nvarchar(100) NULL,
        [ApiBaseUrl] nvarchar(500) NULL,
        [ConnectionTimeoutSeconds] int NOT NULL,
        [MaxRetries] int NOT NULL,
        [RetryDelay] time NOT NULL,
        CONSTRAINT [PK_SmsConfigurations] PRIMARY KEY ([Id])
    );");
        }

        /// <inheritdoc />
        protected override void Down(MigrationBuilder migrationBuilder)
        {
            // ConfigurationDatabase-NNN: refuse to roll back if SMS-only recipients exist.
            // Such a row carries a PhoneNumber and a (legitimately) NULL EmailAddress. The
            // backfill below sets every NULL EmailAddress to '' so the column can revert to
            // NOT NULL — but for an SMS-only recipient that silently destroys its contact
            // info (PhoneNumber is also dropped) and leaves an invalid empty-string email.
            // This guard MUST run before DROP COLUMN [PhoneNumber], while the column is still
            // queryable, so the operator gets a clear error instead of silent data loss.
            migrationBuilder.Sql(@"
IF EXISTS (SELECT 1 FROM [NotificationRecipients] WHERE [EmailAddress] IS NULL AND [PhoneNumber] IS NOT NULL)
    THROW 60000, 'Cannot roll back AddSmsNotifications: SMS-only recipients (PhoneNumber set, EmailAddress NULL) exist. Reassign or delete them before rolling back -- otherwise their PhoneNumber would be dropped and EmailAddress backfilled to an invalid empty string.', 1;");

            migrationBuilder.Sql(@"
IF OBJECT_ID(N'dbo.SmsConfigurations', N'U') IS NOT NULL
    DROP TABLE [SmsConfigurations];");

            migrationBuilder.Sql(@"
IF EXISTS (SELECT 1 FROM sys.columns WHERE Name='PhoneNumber' AND Object_ID=Object_ID('NotificationRecipients'))
    ALTER TABLE [NotificationRecipients] DROP COLUMN [PhoneNumber];");

            // Reversing to NOT NULL requires backfilling existing NULLs first, otherwise the
            // ALTER fails. Mirrors EF's generated default ('') for the previously-required column.
            // The guard above guarantees any remaining NULL here belongs to a pre-existing email
            // recipient that never had an address, not an SMS-only recipient.
            migrationBuilder.Sql("UPDATE [NotificationRecipients] SET [EmailAddress] = '' WHERE [EmailAddress] IS NULL;");
            migrationBuilder.Sql("ALTER TABLE [NotificationRecipients] ALTER COLUMN [EmailAddress] nvarchar(500) NOT NULL;");
        }
    }
}
