-- Recovery: orphan AppUser cleanup.
--
-- Применяется один раз вручную на стейдже/проде после деплоя
-- AuthorizationController + SuperAdminOrganizationsController фиксов
-- (audit 2026-04-27 #1, #2, #7).
--
-- Что делает:
--   1. Находит users у которых OrganizationId указывает на отсутствующую
--      или архивированную организацию.
--   2. Деактивирует таких users (IsActive=false), сбрасывает OrganizationId.
--   3. Отзывает все OpenIddict refresh/access токены этих users
--      (Status='revoked') чтобы существующие сессии оборвались.
--
-- Идемпотентен: повторный запуск ничего не ломает.
-- Не удаляет данные — только статусы. Юзер при необходимости может
-- быть восстановлен ручным UPDATE users SET "IsActive"=true.

BEGIN;

WITH orphan_users AS (
    SELECT u."Id"
    FROM users u
    LEFT JOIN organizations o ON o."Id" = u."OrganizationId"
    WHERE u."IsActive" = true
      AND (
        u."OrganizationId" IS NULL
        OR o."Id" IS NULL
        OR o."IsArchived" = true
      )
      AND NOT EXISTS (
        -- Не трогаем SuperAdmin'ов — у них org=null это норма.
        SELECT 1
        FROM "AspNetUserRoles" ur
        JOIN roles r ON r."Id" = ur."RoleId"
        WHERE ur."UserId" = u."Id" AND r."NormalizedName" = 'SUPERADMIN'
      )
)
UPDATE users
   SET "IsActive" = false,
       "OrganizationId" = NULL
 WHERE "Id" IN (SELECT "Id" FROM orphan_users);

UPDATE "OpenIddictTokens" t
   SET "Status" = 'revoked'
 WHERE t."Status" = 'valid'
   AND t."Subject" IN (
        SELECT u."Id"::text FROM users u
        WHERE u."IsActive" = false
   );

-- Owner-Employee должен оставаться в роли «Администратор» и быть IsActive=true.
-- Если кто-то сменил роль владельца на Кладовщика/Менеджера/Кассира или
-- деактивировал — возвращаем «Администратор» и активируем.
WITH admin_role_per_org AS (
    SELECT r."OrganizationId", r."Id" AS role_id
    FROM employee_roles r
    WHERE r."IsSystem" = true AND r."Name" = 'Администратор'
)
UPDATE employees e
   SET "RoleId"   = ar.role_id,
       "IsActive" = true,
       "FiredAt"  = NULL
  FROM organizations o
  JOIN admin_role_per_org ar ON ar."OrganizationId" = o."Id"
 WHERE e."OrganizationId" = o."Id"
   AND e."UserId" = o."AccountOwnerUserId"
   AND (
        e."RoleId" <> ar.role_id
        OR e."IsActive" = false
   );

COMMIT;
