WITH raw_members AS (
  SELECT member
  FROM app_data
  CROSS JOIN LATERAL jsonb_array_elements(
    CASE
      WHEN jsonb_typeof(value -> 'members') = 'array' THEN value -> 'members'
      ELSE '[]'::jsonb
    END
  ) AS member
  WHERE key = 'members'
),
members AS (
  SELECT
    NULLIF(member ->> 'id', '') AS id,
    NULLIF(member ->> 'username', '') AS username,
    NULLIF(member ->> 'departmentId', '') AS department_id,
    NULLIF(member ->> 'roleId', '') AS role_id,
    COALESCE(member ->> 'phone', '') AS phone,
    COALESCE(member ->> 'password', '') AS password,
    CASE
      WHEN jsonb_typeof(member -> 'isSystem') = 'boolean' THEN (member ->> 'isSystem')::boolean
      ELSE NULL
    END AS is_system,
    COUNT(*) OVER (PARTITION BY NULLIF(member ->> 'username', '')) AS username_count
  FROM raw_members
)
UPDATE users AS u
SET
  username = CASE
    WHEN NULLIF(u.username, '') IS NULL
      AND m.username IS NOT NULL
      AND m.username_count = 1
      AND NOT EXISTS (
        SELECT 1
        FROM users AS other_user
        WHERE other_user.id <> u.id
          AND other_user.username = m.username
      )
      THEN m.username
    ELSE u.username
  END,
  department_id = COALESCE(m.department_id, u.department_id),
  role_id = COALESCE(m.role_id, u.role_id, 'member'),
  phone = COALESCE(m.phone, u.phone, ''),
  password = COALESCE(m.password, u.password, ''),
  is_system = COALESCE(m.is_system, u.is_system, false)
FROM members AS m
WHERE u.id = m.id;
