import {z} from 'zod';
import {EventsSocketsType} from '@config/constants';
import {NewMessageEvent} from '@modules/chats/interfaces';
import {sentryLogs} from '@shared/utils';

import {
  assetDBRequiredFieldsSchema,
  getValidationResult,
  requiredString,
  requiredUserId,
} from './shared';

const reactionDBRequiredFieldsSchema = z
  .object({
    name: requiredString,
    users: z.array(requiredUserId),
  })
  .passthrough();

const newMessageDBRequiredFieldsSchema = z
  .object({
    client_msg_id: requiredString,
    channel: requiredString,
    username: requiredString,
    attachments: z.array(assetDBRequiredFieldsSchema).optional(),
    reactions: z.array(reactionDBRequiredFieldsSchema).optional(),
    hu_data: z
      .object({
        sender_id: requiredUserId,
        message_ts: requiredString,
      })
      .passthrough(),
  })
  .passthrough();

const logNewMessageDBValidation = ({
  event,
  source,
  issues,
}: {
  event: NewMessageEvent;
  source: string;
  issues: string[];
}) => {
  sentryLogs.error({
    message:
      '[Events Validation] New message event has invalid DB-required fields',
    module: 'CHATS',
    component: 'socketEvents',
    data: {
      source,
      eventName: EventsSocketsType.CHATS_V2_NEW_MESSAGE,
      eventTs: event.ts,
      channel: event.channel,
      clientMsgId: event.client_msg_id,
      senderId: event.hu_data?.sender_id,
      messageTs: event.hu_data?.message_ts,
      attachmentsCount: Array.isArray(event.attachments)
        ? event.attachments.length
        : undefined,
      reactionsCount: Array.isArray(event.reactions)
        ? event.reactions.length
        : undefined,
      issues,
    },
  });
};

export const logNewMessageEventDBValidationIssues = (
  event: NewMessageEvent,
  source: string,
) => {
  const validation = getValidationResult(
    newMessageDBRequiredFieldsSchema,
    event,
  );
  if (!validation.success) {
    logNewMessageDBValidation({event, source, issues: validation.issues});
  }
};
