
import Redis from 'ioredis'
import { type } from 'os'
const unflatten = require('flat').unflatten
var flatten = require('flat')
import ListContactsServiceCache from "../services/ContactServices/ListContactsServiceCache"
import { redisConn } from './TicketCache'

import SchedulingNotify from '../models/SchedulingNotify'

import { format } from "date-fns";
import ptBR from 'date-fns/locale/pt-BR';

import { escapeCharCache } from './ContactsCache'


const deleteScheduleByTicketIdCache = async (ticketId: string | number) => {

    const redis: any = await redisConn();

    if (!redis) return

   //  if (redis.status !== 'connect') return

    const schedule_cache: any = await redis.hgetall(`schedule:${ticketId}`)

    try {
        if (schedule_cache && Object.keys(schedule_cache).length > 0) {

            await redis.del(`schedule:${ticketId}`)

            console.log(`Schedule cache ticketId ${schedule_cache.ticketId} deleted!`)
        }
        else {
            console.log('SCHEDULE CACHE NOT FOUND!')
        }
    } catch (error) {
        console.log(`There was an error on deleteScheduleByTicketIdCache:  ${error}`)
    }

    // await redis.quit()
}





const updateScheduleCacheByTicketId = async (scheduleNotify: any) => {

    const redis: any = await redisConn();

    if (!redis) return

   //  if (redis.status !== 'connect') return

    const pipeline = redis.pipeline()

    let entries = Object.entries(scheduleNotify)

    entries.forEach((e: any) => {
        pipeline.hset(`schedule:${scheduleNotify.ticketId}`, e[0], e[1])
    })

    await pipeline.exec(() => { console.log("schedule Key/value inserted/updated") });

    // await redis.quit()

}




const createSchedulingNotifyCache = async (scheduleNotify: any) => {

    const redis: any = await redisConn();

    if (!redis) return

   //  if (redis.status !== 'connect') return  

    let date_time: any = format(new Date(scheduleNotify.schedulingTime), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR }).split(' ')

    delete scheduleNotify.schedulingTime
    delete scheduleNotify.updatedAt
    delete scheduleNotify.createdAt
    delete scheduleNotify.schedulingDate

    console.log('created date_time: ', date_time)

    scheduleNotify.date = date_time[0]
    scheduleNotify.date_escaped = escapeCharCache(date_time[0]) 
    scheduleNotify.hour = date_time[1].split(':')[0]
    scheduleNotify.minute = date_time[1].split(':')[1] 

    await redis.hmset(`schedule:${scheduleNotify.ticketId}`, scheduleNotify);

    console.log(`${scheduleNotify.length} SCHEDULE NOTIFY INSERTED IN CACHE!`)

    // await redis.quit()

}


async function searchScheduleCache(date: string, hour: number | string, minute: number | string) {

    const redis: any = await redisConn();

    if (!redis) return

   //  if (redis.status !== 'connect') return null

    date = escapeCharCache(date).trim() 
 
    const response: any = await redis.call('FT.SEARCH', 'idx_schedule', `(@date_escaped:${date}) (@hour:${hour}) (@minute:${minute})`)
    // await redis.quit()


    if (response.length === 1) {
        return []
    }

    const results: any = []

    for (let n = 2; n < response.length; n += 2) {
        const result: any = {}
        const fieldNamesAndValues = response[n]

        for (let m = 0; m < fieldNamesAndValues.length; m += 2) {
            const k = fieldNamesAndValues[m]
            const v = fieldNamesAndValues[m + 1]
            result[k] = v
        }

        results.push(result)
    }

    return results
}

const loadSchedulesCache = async () => {

    await createScheduleIndexCache('idx_schedule')

    const redis: any = await redisConn();

    if (!redis) return

   //  if (redis.status !== 'connect') return

    let schedules: any = await SchedulingNotify.findAll({ raw: true, attributes: ["id", "statusChatEndId", "ticketId", "schedulingTime", "message"] });

    // console.log('SCHEDULE NOTIFY CACHE2: ', schedules)


    const pipeline = redis.pipeline()

    for (let i = 0; i < schedules.length; i++) {

        let date_time: any = format(new Date(schedules[i].schedulingTime), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR }).split(' ')

        delete schedules[i].schedulingTime

        console.log('date_time: ', date_time)

        schedules[i].date = date_time[0]
        schedules[i].date_escaped = escapeCharCache(date_time[0])

        schedules[i].hour = date_time[1].split(':')[0]
        schedules[i].minute = date_time[1].split(':')[1]

        pipeline.hmset(`schedule:${schedules[i].ticketId}`, schedules[i]);
    }

    await pipeline.exec(() => { console.log(`${schedules.length} SCHEDULES NOTIFY INSERTED IN CACHE!`) });

    // await redis.quit()


    // let test = await searchScheduleCache('2022-12-16', '18', '30')

    // console.log('--------------> TEST: ', test)

}

const createScheduleIndexCache = async (hashIndex: string) => {

    const redis: any = await redisConn();

    if (!redis) return

   //  if (redis.status !== 'connect') return

    try {

        const lst_index_redis: any = await redis.call('FT._LIST')

        if (lst_index_redis.includes(hashIndex)) {
            console.log('entrou...')
            await redis.call('FT.DROPINDEX', hashIndex)
        }

        const response = await redis.call('FT.CREATE', hashIndex, 'ON', 'HASH', 'PREFIX', '1', 'schedule:', 'SCHEMA', 'id', 'TEXT', 'SORTABLE', 'date_escaped', 'TEXT', 'SORTABLE', 'hour', 'TEXT', 'SORTABLE', 'minute', 'TEXT', 'SORTABLE')

        console.log('Schedule index created: ', response)

    } catch (error) {
        console.log('There was an error on createScheduleIndexCache: ', error)
    }

    // await redis.quit()
}

export {
    loadSchedulesCache,
    searchScheduleCache,
    updateScheduleCacheByTicketId,
    createSchedulingNotifyCache,
    deleteScheduleByTicketIdCache
}