/**
 * This file is part of the Meeds project (https://meeds.io/).
 *
 * Copyright (C) 2020 - 2025 Meeds Association contact@meeds.io
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
package org.exoplatform.commons.notification.impl.jpa.web.entity;

import java.util.Calendar;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.NamedQuery;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table;

@Entity(name = "NotificationsWebUsersEntity")
@Table(name = "NTF_WEB_NOTIFS_USERS")
@NamedQuery(name = "NotificationsWebUsersEntity.getNumberOnBadge", query = "SELECT COUNT(u) FROM NotificationsWebUsersEntity u " +
  "WHERE u.receiver = :userId " +
  "AND u.resetNumberOnBadge = FALSE ")
@NamedQuery(
    name = "NotificationsWebUsersEntity.countUnreadByPlugin",
    query = "SELECT w.type, COUNT(u) FROM NotificationsWebUsersEntity u " +
      " INNER JOIN u.webNotification w " +
      " WHERE u.receiver = :userId " +
      " AND u.read = FALSE" +
      " GROUP BY w.type")
@NamedQuery(name = "NotificationsWebUsersEntity.findNotifsWithBadge", query = "SELECT u FROM NotificationsWebUsersEntity u " +
    "WHERE u.receiver = :userId " +
    "AND u.resetNumberOnBadge = FALSE ")
@NamedQuery(
name = "NotificationsWebUsersEntity.findNotifsWithBadgeByPlugins",
query = "SELECT u FROM NotificationsWebUsersEntity u " +
    " INNER JOIN u.webNotification w " +
    " ON w.type IN (:pluginIds)" +
    " WHERE u.receiver = :userId " +
    " AND u.resetNumberOnBadge = FALSE ")
@NamedQuery(
  name = "NotificationsWebUsersEntity.findUnreadByUserAndPlugins",
  query = "SELECT u FROM NotificationsWebUsersEntity u " +
    " INNER JOIN u.webNotification w " +
    " ON w.type IN (:pluginIds)" +
    " WHERE u.receiver = :userId " +
    " AND u.read = FALSE ")
@NamedQuery(name = "NotificationsWebUsersEntity.markWebNotifsAsReadByUser", query = "UPDATE NotificationsWebUsersEntity u " +
    "SET u.read = TRUE " +
    "WHERE u.receiver = :userId " +
    "AND u.read = FALSE ")
@NamedQuery(
  name = "NotificationsWebUsersEntity.findWebNotifsByPluginFilter",
  query = "SELECT distinct(u) FROM NotificationsWebUsersEntity u " +
    " INNER JOIN u.webNotification w " +
    " ON w.type IN (:pluginIds)" +
    " WHERE u.receiver = :userId " +
    " AND u.showPopover= :isOnPopover " +
    " ORDER BY u.updateDate DESC "
)
@NamedQuery(
  name = "NotificationsWebUsersEntity.findNotificationsByTypeAndParams",
  query = "SELECT distinct(u) FROM NotificationsWebUsersEntity u " +
    " INNER JOIN u.webNotification w" +
    " ON w.type IN (:pluginIds)" +
    " INNER JOIN w.parameters p" +
    " ON p.name = :paramName" +
    " AND p.value = :paramValue" +
    " WHERE u.receiver = :receiver" +
    " ORDER BY u.updateDate DESC ")
@NamedQuery(name = "NotificationsWebUsersEntity.findWebNotifsByUserFilter", query = "SELECT u FROM NotificationsWebUsersEntity u " +
    "JOIN FETCH u.webNotification w " +
    "WHERE u.receiver = :userId " +
    "ORDER BY u.updateDate DESC ")
@NamedQuery(name = "NotificationsWebUsersEntity.findWebNotifsByPopoverFilter", query = "SELECT u FROM NotificationsWebUsersEntity u " +
    "JOIN FETCH u.webNotification w " +
    "WHERE u.receiver = :userId " +
    "AND u.showPopover= :isOnPopover " +
    "ORDER BY u.updateDate DESC ")
@NamedQuery(name = "NotificationsWebUsersEntity.findUnreadNotification", query = "SELECT u FROM NotificationsWebUsersEntity u " +
    "JOIN FETCH u.webNotification w " +
    "JOIN u.webNotification.parameters  p " +
    "WHERE w.type= :pluginId " +
    "AND p.name = :paramName " +
    "AND p.value LIKE :paramValue " +
    "AND u.receiver = :userId " +
    "AND u.read = FALSE " +
    "ORDER BY u.updateDate DESC ")
@NamedQuery(name = "NotificationsWebUsersEntity.findWebNotifsOfUserByLastUpdatedDate", query = "SELECT u FROM NotificationsWebUsersEntity u " +
    "WHERE u.receiver = :userId " +
    "AND u.updateDate < :calendar ")
@NamedQuery(name = "NotificationsWebUsersEntity.findWebNotifsByLastUpdatedDate", query = "SELECT u FROM NotificationsWebUsersEntity u " +
    "JOIN FETCH u.webNotification w " +
    "WHERE u.updateDate < :calendar ")
public class WebUsersEntity {
  @Id
  @Column(name = "WEB_NOTIFS_USERS_ID")
  @SequenceGenerator(name="SEQ_NTF_WEB_USERS", sequenceName="SEQ_NTF_WEB_USERS", allocationSize = 1)
  @GeneratedValue(strategy=GenerationType.AUTO, generator="SEQ_NTF_WEB_USERS")
  private long id;

  @ManyToOne(fetch=FetchType.LAZY)
  @JoinColumn(name = "WEB_NOTIF_ID")
  private WebNotifEntity webNotification;

  @Column(name = "RECEIVER")
  private String receiver;

  @Column(name = "UPDATE_DATE")
  private Calendar updateDate;

  @Column(name = "IS_READ")
  private boolean read;

  @Column(name = "SHOW_POPOVER")
  private boolean showPopover;

  @Column(name = "RESET_NUMBER_BADGE")
  private boolean resetNumberOnBadge;

  public long getId() {
    return id;
  }

  public WebNotifEntity getNotification() {
    return webNotification;
  }

  public WebUsersEntity setNotification(WebNotifEntity webNotification) {
    this.webNotification = webNotification;
    webNotification.addReceiver(this);
    return this;
  }
  public String getReceiver() {
    return receiver;
  }

  public WebUsersEntity setReceiver(String receiver) {
    this.receiver = receiver;
    return this;
  }

  public Calendar getUpdateDate() {
    return updateDate;
  }

  public WebUsersEntity setUpdateDate(Calendar updateDate) {
    this.updateDate = updateDate;
    return this;
  }

  public boolean isRead() {
    return read;
  }

  public WebUsersEntity setRead(boolean read) {
    this.read = read;
    return this;
  }

  public boolean isShowPopover() {
    return showPopover;
  }

  public WebUsersEntity setShowPopover(boolean showPopover) {
    this.showPopover = showPopover;
    return this;
  }

  public boolean isResetNumberOnBadge() {
    return resetNumberOnBadge;
  }

  public void setResetNumberOnBadge(boolean resetNumberOnBadge) {
    this.resetNumberOnBadge = resetNumberOnBadge;
  }
}
