import { Injectable, NotFoundException } from '@nestjs/common';
import { CreateContactDto } from '../dto/create-contact.dto';
import { FindContactsDto } from '../dto/find-contacts.dto';
import { UpdateContactStatusDto } from '../dto/update-contact-status.dto';
import { ContactRepository } from '../repositories/contact.repository';
import { Contact } from '../entities/contact.entity';
import { PaginatedResult } from 'src/common/interfaces/pagination.interface';
import { ContactStatusEnum } from '../interface/interface';
import { EntityManager } from '@mikro-orm/postgresql';
import { ContactScope } from '../interface/interface';
import { Restaurant } from '../../restaurants/entities/restaurant.entity';

@Injectable()
export class ContactService {
  constructor(
    private readonly contactRepository: ContactRepository,
    private readonly em: EntityManager,
  ) { }

  async create(dto: CreateContactDto, restId?: string, slug?: string): Promise<Contact> {


    let restaurant: Restaurant | null = null;

    if ((restId || slug) && dto.scope === ContactScope.RESTAURANT) {
      restaurant = await this.em.findOne(Restaurant, {
        ...(restId ? { id: restId } : {})
        , ...(slug ? { slug: slug } : {})
      });
      if (!restaurant) {
        throw new NotFoundException(`Restaurant with ID ${restId} not found`);
      }
    }

    const contact = this.contactRepository.create({
      ...dto,
      status: ContactStatusEnum.New,
      restaurant,
    });
    await this.em.persistAndFlush(contact);
    return contact;
  }

  async findAllPaginatedAdmin(dto: FindContactsDto, restaurantId?: string): Promise<PaginatedResult<Contact>> {
    return this.contactRepository.findAllPaginated({
      page: dto.page,
      limit: dto.limit,
      search: dto.search,
      orderBy: dto.orderBy,
      order: dto.order,
      status: dto.status,
      scope: ContactScope.RESTAURANT,
      restaurantId
    });
  }
  async findAllPaginatedSuper(dto: FindContactsDto): Promise<PaginatedResult<Contact>> {
    return this.contactRepository.findAllPaginated({
      page: dto.page,
      limit: dto.limit,
      search: dto.search,
      orderBy: dto.orderBy,
      order: dto.order,
      status: dto.status,
      scope: ContactScope.APPLICATION
    });
  }

  async findOne(id: string, restaurantId?: string): Promise<Contact> {
    const where: any = { id };
    if (restaurantId) {
      where.restaurant = restaurantId;
    }

    const contact = await this.contactRepository.findOne(where);
    if (!contact) {
      throw new NotFoundException(`Contact with ID ${id} not found`);
    }
    return contact;
  }

  async updateStatus(id: string, dto: UpdateContactStatusDto, restaurantId?: string): Promise<Contact> {
    const where: any = { id };
    if (restaurantId) {
      where.restaurant = restaurantId;
    }

    const contact = await this.contactRepository.findOne(where);
    if (!contact) {
      throw new NotFoundException(`Contact with ID ${id} not found`);
    }
    contact.status = dto.status;
    await this.em.persistAndFlush(contact);
    return contact;
  }

  async remove(id: string, restaurantId?: string): Promise<void> {
    const where: any = { id };
    if (restaurantId) {
      where.restaurant = restaurantId;
    }

    const contact = await this.contactRepository.findOne(where);
    if (!contact) {
      throw new NotFoundException(`Contact with ID ${id} not found`);
    }
    await this.em.removeAndFlush(contact);
  }
}
