import { PrismaClient } from '@prisma/client';
import {
    EmployeeDbInsertType,
    EmployeeUpdateInputType,
    IdType,
} from '../../declarations/validations';

export interface IEmployeeListService {}

export default class EmployeeDatabaseService implements IEmployeeListService {
    private prisma = new PrismaClient();

    async insertEmployee(employee: EmployeeDbInsertType) {
        const {
            username,
            passwordHash,
            mail,
            ...employeeProperties
        } = employee;

        return this.prisma.profile
            .create({
                data: {
                    mail,
                    ...employeeProperties,
                    user: {
                        create: {
                            username,
                            passwordHash,
                            mail,
                            roles: {
                                connect: [{ id: 2 }], // TODO dynamic by seed
                            },
                        },
                    },
                },
            })
            .catch((e) => {
                throw e;
            })
            .finally(async () => {
                await this.prisma.$disconnect();
            });
    }

    async findEmployeeById(employeeId: IdType) {
        return this.prisma.profile
            .findFirst({
                where: {
                    id: employeeId,
                    user: {
                        roles: {
                            some: {
                                name: 'employee', // TODO enum
                            },
                        },
                    },
                },
            })
            .catch((e) => {
                throw e;
            })
            .finally(async () => {
                await this.prisma.$disconnect();
            });
    }

    async findAllEmployees() {
        return this.prisma.profile
            .findMany({
                where: {
                    user: {
                        roles: {
                            some: {
                                name: 'employee', // TODO enum
                            },
                        },
                    },
                },
                orderBy: [
                    {
                        firstname: 'asc',
                    },
                    {
                        lastname: 'asc',
                    },
                ],
            })
            .catch((e) => {
                throw e;
            })
            .finally(async () => {
                await this.prisma.$disconnect();
            });
    }

    async updateEmployee(employee: EmployeeUpdateInputType) {
        const { id, ...updatedObject } = employee;
        return this.prisma.profile
            .update({
                where: {
                    id,
                },
                data: {
                    ...updatedObject,
                },
            })
            .catch((e) => {
                throw e;
            })
            .finally(async () => {
                await this.prisma.$disconnect();
            });
    }

    async deleteEmployee(employeeId: number) {
        return this.prisma.profile
            .delete({
                where: {
                    id: employeeId,
                },
            })
            .catch((e) => {
                throw e;
            })
            .finally(async () => {
                await this.prisma.$disconnect();
            });
    }
}
