import {eq, inArray, sql, isNull} from 'drizzle-orm';
import {db, DBTransaction} from '@db/index';
import {users} from '@db/schema';
import {ChatUserStatus} from '@modules/chats/interfaces';

import {InsertUser} from '../interfaces';

export const getUserById = async (id: number) => {
  const [user] = await db.instance.select().from(users).where(eq(users.id, id));
  return user;
};

export const getKnownUsersByIds = async (ids: number[]) => {
  const knownUsers = await db.instance
    .select({id: users.id})
    .from(users)
    .where(inArray(users.id, ids));
  return knownUsers.map(user => user.id);
};

export const insertUsers = async (values: InsertUser[], tx?: DBTransaction) => {
  if (!values.length) {
    return;
  }

  const builder = tx ?? db.instance;
  return await builder
    .insert(users)
    .values(values)
    .onConflictDoUpdate({
      target: users.id,
      set: {
        name: sql`excluded.name`,
        tz: sql`excluded.tz`,
        first_name: sql`excluded.first_name`,
        last_name: sql`excluded.last_name`,
        email: sql`excluded.email`,
        employee_internal_id: sql`excluded.employee_internal_id`,
        picture_asset_url: sql`excluded.picture_asset_url`,
        status: sql`excluded.status`,
        deleted_at: sql`excluded.deleted_at`,
        version: sql`excluded.version`,
        updated: sql`excluded.updated`,
      },
      setWhere: sql`${users.version} < excluded.version 
      OR ${isNull(users.picture_asset_url)}
      OR ${users.picture_asset_url} <> excluded.picture_asset_url`,
    });
};

export const updateUserStatus = async ({
  id,
  status,
}: {
  id: number;
  status: ChatUserStatus;
}) => {
  return await db.instance
    .update(users)
    .set({
      status,
      deleted_at: status === ChatUserStatus.Deleted ? Date.now() : null,
    })
    .where(eq(users.id, id));
};

export const getUsersById = async (ids: number[]) => {
  return await db.instance.select().from(users).where(inArray(users.id, ids));
};

export const getAllUsers = async () => {
  return await db.instance
    .select({
      id: users.id,
      first_name: users.first_name,
      last_name: users.last_name,
      picture_asset_url: users.picture_asset_url,
      status: users.status,
      deleted_at: users.deleted_at,
    })
    .from(users);
};
