import { prisma } from "@/module/_global";
import { funGetUserById } from "@/module/auth";
import { createLogUserMobile } from '@/module/user';
import _ from "lodash";
import moment from "moment";
import "moment/locale/id";
import { NextResponse } from "next/server";
import { Frequency, RRule } from 'rrule';

//GET ALL CALENDER
export async function GET(request: Request) {
    try {
        const { searchParams } = new URL(request.url);
        const idDivision = searchParams.get("division");
        const isDate = searchParams.get("date")
        const user = searchParams.get("user")

        const userMobile = await funGetUserById({ id: String(user) })
        if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") {
            return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 });
        }


        if (idDivision != "null" && idDivision != null && idDivision != undefined && idDivision != "") {
            const cekDivision = await prisma.division.count({
                where: {
                    id: idDivision,
                    // isActive: true
                }
            })

            if (cekDivision == 0) {
                return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan" }, { status: 200 });
            }

            const data = await prisma.divisionCalendarReminder.findMany({
                where: {
                    isActive: true,
                    idDivision: idDivision,
                    dateStart: new Date(String(isDate)),
                    DivisionCalendar: {
                        isActive: true
                    }
                },
                select: {
                    id: true,
                    idCalendar: true,
                    timeStart: true,
                    dateStart: true,
                    timeEnd: true,
                    dateEnd: true,
                    createdAt: true,
                    status: true,
                    DivisionCalendar: {
                        select: {
                            title: true,
                            desc: true,
                            User: {
                                select: {
                                    name: true
                                }
                            }
                        }
                    }
                },
                orderBy: [
                    {
                        dateStart: 'asc'
                    },
                    {
                        timeStart: 'asc'
                    },
                    {
                        timeEnd: 'asc'
                    }
                ]
            });

            const allOmit = data.map((v: any) => ({
                ..._.omit(v, ["DivisionCalendar", "User"]),
                title: v.DivisionCalendar.title,
                desc: v.DivisionCalendar.desc,
                user_name: v.DivisionCalendar.User.name,
                timeStart: moment.utc(v.timeStart).format('HH:mm'),
                timeEnd: moment.utc(v.timeEnd).format('HH:mm')
            }))


            return NextResponse.json({ success: true, message: "Berhasil mendapatkan kalender", data: allOmit }, { status: 200 });

        } else {
            return NextResponse.json({ success: false, message: "Gagal mendapatkan kalender, data tidak ditemukan" }, { status: 200 });
        }

    } catch (error) {
        console.error(error)
        return NextResponse.json({ success: false, message: "Gagal mendapatkan kalender, data tidak ditemukan (error: 500)" }, { status: 500 });
    }
}


//CREATE CALENDER
export async function POST(request: Request) {
    try {
        const { idDivision, title, desc, timeStart, timeEnd, dateStart, dateEnd, repeatEventType, member, linkMeet, repeatValue, user } = (await request.json());

        const userMobile = await funGetUserById({ id: String(user) })
        if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") {
            return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 });
        }

        const userId = userMobile.id
        const cekDivision = await prisma.division.count({
            where: {
                id: idDivision,
                isActive: true
            }
        })

        if (cekDivision == 0) {
            return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan" }, { status: 200 });
        }

        const y = new Date('1970-01-01 ' + timeStart)
        const x = new Date('1970-01-01 ' + timeEnd)
        const timeStartFix = new Date(y.getTime() - (y.getTimezoneOffset() * 60000)).toISOString()
        const timeEndFix = new Date(x.getTime() - (x.getTimezoneOffset() * 60000)).toISOString()

        const dateStartFix = moment(dateStart, 'DD-MM-YYYY').format('YYYY-MM-DD')


        const data = await prisma.divisionCalendar.create({
            data: {
                idDivision,
                createdBy: String(userId),
                title,
                dateStart: new Date(dateStartFix),
                timeStart: timeStartFix,
                timeEnd: timeEndFix,
                linkMeet,
                repeatEventTyper: repeatEventType,
                desc,
                repeatValue: Number(repeatValue)
            },
            select: {
                id: true,
            }
        });


        const freq: Frequency = repeatEventType === "yearly" ? RRule.YEARLY :
            repeatEventType === "monthly" ? RRule.MONTHLY :
                repeatEventType === "weekly" ? RRule.WEEKLY :
                    repeatEventType === "daily" ? RRule.DAILY :
                        repeatEventType === "hourly" ? RRule.HOURLY :
                            repeatEventType === "minutely" ? RRule.MINUTELY :
                                RRule.SECONDLY;

        const rule = new RRule({
            freq,
            interval: 1,
            dtstart: new Date(dateStartFix),
            count: repeatValue
        });

        const hasil = rule.all().map(recurrenceDate => ({
            idDivision: idDivision,
            idCalendar: data.id,
            dateStart: recurrenceDate,
            timeStart: timeStartFix,
            timeEnd: timeEndFix,
            dateEnd: recurrenceDate
        }));

        const insertReminder = await prisma.divisionCalendarReminder.createMany({
            data: hasil
        })


        const omitMember = member.map((v: any) => ({
            ..._.omit(v, ["name", "idUser", "img"]),
            idCalendar: data.id,
            idUser: v.idUser
        }))


        const insertMember = await prisma.divisionCalendarMember.createMany({
            data: omitMember
        });


        // create log user
        const log = await createLogUserMobile({ act: 'CREATE', desc: 'User membuat data acara kalender', table: 'divisionCalendar', data: data.id, user: String(userId) })

        return NextResponse.json({ success: true, message: "Berhasil membuat acara kalender" }, { status: 200 });

    } catch (error) {
        console.error(error);
        return NextResponse.json({ success: false, message: "Gagal membuat acara kalender, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 });
    }
}



// CEK TGL AVAILABLE
export async function PUT(request: Request) {
    try {
        const { idDivision, title, desc, timeStart, timeEnd, dateStart, dateEnd, repeatEventTyper, member, linkMeet, repeatValue, user } = (await request.json());

        const userMobile = await funGetUserById({ id: String(user) })
        if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") {
            return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 });
        }

        const userId = userMobile.id
        const division = await prisma.division.findUnique({
            where: {
                id: idDivision
            }
        })

        const y = new Date('1970-01-01 ' + timeStart)
        const x = new Date('1970-01-01 ' + timeEnd)
        const timeStartFix = new Date(y.getTime() - (y.getTimezoneOffset() * 60000)).toISOString()
        const timeEndFix = new Date(x.getTime() - (x.getTimezoneOffset() * 60000)).toISOString()

        const cek = await prisma.divisionCalendarReminder.findMany({
            where: {
                isActive: true,
                Division: {
                    idGroup: division?.idGroup
                },
                OR: [
                    {
                        dateStart: new Date(dateStart),
                        DivisionCalendar: {
                            title: {
                                equals: title,
                                mode: "insensitive"
                            },
                        }
                    },
                    {
                        dateStart: new Date(dateStart),
                        OR: [
                            {
                                timeStart: { //13:00
                                    lte: timeStartFix, //13:30
                                },
                                timeEnd: { //14:00
                                    gt: timeStartFix, //13:30
                                }
                            },
                            {
                                timeStart: { //07:00
                                    lt: timeEndFix, //07:30
                                },
                                timeEnd: { //08:00
                                    gt: timeEndFix, //07:30
                                }
                            },
                            {
                                timeStart: { //07:00
                                    gt: timeStartFix, //06:30
                                },
                                timeEnd: { //08:00
                                    lte: timeEndFix, //09:30
                                }
                            }
                        ]

                    }
                ]
            },
            select: {
                id: true,
                dateStart: true,
                timeStart: true,
                timeEnd: true,
                DivisionCalendar: {
                    select: {
                        title: true,
                    }
                },
                Division: {
                    select: {
                        name: true
                    }
                }
            }
        })

        const dataSama = cek.map((v: any) => ({
            ..._.omit(v, ["DivisionCalendar", "Division"]),
            title: v.DivisionCalendar.title,
            divisi: v.Division.name
        }))

        if (cek.length > 0) {
            return NextResponse.json({ success: false, message: "Tidak dapat membuat acara kalender, acara kalender sudah ada pada tanggal tersebut", data: dataSama }, { status: 400 });
        } else {
            return NextResponse.json({ success: true, message: "Berhasil membuat acara kalender" }, { status: 200 });
        }


    } catch (error) {
        console.error(error)
        return NextResponse.json({ success: false, message: "Gagal membuat acara kalender, coba lagi nanti (error: 500)" }, { status: 500 });
    }
}