import { Injectable, HttpException, HttpStatus, Res, Inject } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Like, Not, ILike, In } from 'typeorm';

// Entities Files
import { Constants } from 'src/common/constants';
import { Settings } from '../../entities/settings.entity';

// DTO Files
import { SettingsUpdateDto } from './dtos/settings-update.dto';

@Injectable()
export class SettingsService {
    constructor(
        @InjectRepository(Settings)
        private Settings: Repository<Settings>
    ) { }

    /**
     * Retrieves a paginated list of platform settings.
     */
    async list(param, queryParam: any, authUser: any) {
        const reqPage = queryParam.page ? queryParam.page : 1;
        const page = reqPage - 1;
        const pageSize = queryParam.per_page ? queryParam.per_page : Constants.categories_list;
        const offset = page * pageSize;
        const nextPage = page + 1;
        const nextOffset = nextPage * pageSize;

        let sortByArr = {
            created_at: 'settings.created_at',
        };

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

        let query = await this.Settings
            .createQueryBuilder('settings')
            .where('setting_type = :type', { type: param.type })
            .select([
                'settings.id as id', 'settings.type as type', 'settings.value as value', 'settings.name as name', 'settings.created_at as created_at'
            ])
            .orderBy(sort_by, sort_type);

        let total = (await query.getRawMany()).length;
        let results = await query.limit(pageSize).offset(offset).getRawMany();

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

    /**
     * Retrieves a paginated list of general settings.
     
     */
    async general(queryParam: any, authUser: any) {
        const reqPage = queryParam.page ? queryParam.page : 1;
        const page = reqPage - 1;
        const pageSize = queryParam.per_page ? queryParam.per_page : Constants.categories_list;
        const offset = page * pageSize;
        const nextPage = page + 1;
        const nextOffset = nextPage * pageSize;

        let sortByArr = {
            created_at: 'settings.created_at',
        };

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

        let query = await this.Settings
            .createQueryBuilder('settings')
            .where('setting_type = :type', { type: 'general' })
            .select([
                'settings.id as id', 'settings.type as type', 'settings.value as value', 'settings.name as name', 'settings.created_at as created_at'
            ])
            .orderBy(sort_by, sort_type);

        let total = (await query.getRawMany()).length;
        let results = await query.limit(pageSize).offset(offset).getRawMany();

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

    /**
     * Updates a list of settings.
    
     */
    async update(request: SettingsUpdateDto) {
        if (request.request_array.length > 0) {
            for await (const req of request.request_array) {
                const exists = await this.Settings.findOne({ where: [{ id: req['id'] }] });
                if (exists) {
                    exists['value'] = req['value'];
                    await this.Settings.save(exists);
                }
            }
        }

        return;
    }

}
