import { Injectable,HttpException,HttpStatus, Res, Inject } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Like, Not, ILike  } from 'typeorm';
import { classToPlain } from 'class-transformer';
import { responseMessages } from '../../messages/response-messages';

// Entities Files
import { Constants } from 'src/common/constants';
import { Faqs } from '../../entities/faqs.entity';
import { Users, UserRoles } from '../../entities/users.entity';

// DTO Files
import { AdvertisementRepository } from './advertisements.repository';
import { Advertisement } from 'src/entities/advertisement.entity';

@Injectable()
export class AdvertisementService {
    constructor(
        private advertisementRepository: AdvertisementRepository,

        @InjectRepository(Advertisement)
        private Advertisement: Repository<Advertisement>,

    ) {}

    async list(queryParam:any,user:any)
    {
        const reqPage = queryParam.page ? queryParam.page : 0;
        const page = queryParam.page - 1;
        const pageSize = queryParam.per_page ? queryParam.per_page : Constants.faqs_list;
        const offset = page * pageSize;
        const nextPage = page + 1;
        const nextOffset = nextPage * pageSize;

        let sortByArr = {
            button_lable : 'advertisement.button_lable',
            is_active : 'advertisement.is_active',
            advertisement_for : 'advertisement.advertisement_for',
            created_at : 'advertisement.created_at',
        };

        let sort_by = queryParam.sort_by || 'created_at';
        let sort_type = queryParam.sort || 'ASC';
        sort_by = sortByArr[sort_by];

        let query = await this.Advertisement
        .createQueryBuilder('advertisement')
        .orderBy(sort_by,sort_type);

        if((user.role != UserRoles.ADMIN)){
            query = query.andWhere('advertisement.is_active = :is_active', { is_active: true })
        } 

        if (queryParam.search) {
            query = query.andWhere(`(advertisement.button_lable ILIKE :search)`, { search: `%${queryParam.search}%` });
        }
        if(queryParam.advertisement_for){
            query = query.andWhere(`(advertisement.advertisement_for = :advertisement_for)`, { advertisement_for: queryParam.advertisement_for });
        }
       
        if(reqPage !== 0){
            query = query.skip(offset).take(pageSize);
        }

        const [results, total] = await query.getManyAndCount();

        return {
            data: results,
            total : total,
            hasMoreResults : (total > nextOffset) ? 1 : 0,
        }
    }

    async detail(param : any)
    {
        const advertisement = await this.Advertisement.createQueryBuilder('advertisement')
        .where('advertisement.id = :id', { id : param.advertisement_id })
        .getOne();

        if(!advertisement){
            throw  new HttpException(responseMessages.en.advertisement.not_exists,HttpStatus.NOT_FOUND);
        }

        return { data : advertisement }
    }

    async create(request: any, authUser:any)
    {
        request['created_by'] = authUser;
        this.advertisementRepository.createData(request);
        return;
    }

    async update(request : any,params : any,authUser:any)
    {
        const advertisement = await this.Advertisement.findOne({where:[{id : params.advertisement_id}]});
        if(!advertisement){
            throw  new HttpException(responseMessages.en.advertisement.not_exists,HttpStatus.NOT_FOUND);
        }

        advertisement['button_lable'] = request.button_lable;
        advertisement['link'] = request.link;
        advertisement['banner'] = request.banner;
        advertisement['mobile_banner'] = request.mobile_banner;
        advertisement['updated_by'] = authUser;
        await  this.Advertisement.save(advertisement);
        return;
    }

    async delete(params : any)
    {
        const advertisement = await this.Advertisement.findOne({where: [{ id: params.advertisement_id }] });

        if (!advertisement) {
            throw  new HttpException(responseMessages.en.advertisement.not_exists,HttpStatus.NOT_FOUND);
        }

        await this.Advertisement.delete(params.advertisement_id);
        return;
    }

    async changeStatus(params : any)
    {
        let advertisement = await this.Advertisement.findOne({ where: [{ id: params.advertisement_id }] });

        if(!advertisement){
            throw  new HttpException(responseMessages.en.advertisement.not_exists,HttpStatus.NOT_FOUND);
        }

        advertisement['is_active'] = (advertisement.is_active == true) ? false : true;
        await this.Advertisement.save(advertisement);
        return;
    }
}
