import { Injectable } from "@nestjs/common";
import { Result } from "src/common/errors/result-error.factory";
import { toDateFromString } from "src/common/utils/date-utils";
import { EmployeeDetailedDto } from "src/identity-and-account/employees/employee-detailed.dto";
import { toCompanyCodeFromString } from "src/identity-and-account/employees/employee.utils";
import { toBooleanFromString } from "src/identity-and-account/employees/services/employees-get.service";
import { PrismaPostgresService } from "prisma/postgres/prisma-postgres.service";
import { Users } from "prisma/postgres/generated/prisma/client/postgres/client";

@Injectable()
export class EmployeesCreateService {
    constructor(private readonly prisma: PrismaPostgresService) { }

    async createEmployee(dto: EmployeeDetailedDto): Promise<Result<boolean, string>> {
        const normalized_access = toBooleanFromString(dto.user_module_access);
        const supervisor_id = await this.toIdFromFullName(dto.supervisor_full_name);
        const company_code = toCompanyCodeFromString(dto.company_name);
        const first_work_day = toDateFromString(dto.first_work_day);

        await this.prisma.$transaction(async (tx) => {
            const user: Users = await tx.users.create({
                data: {
                    first_name: dto.first_name,
                    last_name: dto.last_name,
                    email: dto.email,
                    phone_number: dto.phone_number,
                    residence: dto.residence,
                    user_module_access: {
                        create: {
                            dashboard: normalized_access.dashboard,
                            employee_list: normalized_access.employee_list,
                            employee_management: normalized_access.employee_management,
                            personal_profile: normalized_access.personal_profile,
                            timesheets: normalized_access.timesheets,
                            timesheets_approval: normalized_access.timesheets_approval,
                        },
                    },
                },
            });
            return tx.employees.create({
                data: {
                    user_id: user.id,
                    external_payroll_id: dto.external_payroll_id,
                    daily_expected_hours: dto.daily_expected_hours,
                    company_code: company_code,
                    job_title: dto.job_title,
                    first_work_day: first_work_day,
                    is_supervisor: dto.is_supervisor,
                    supervisor_id: supervisor_id,
                    schedule_preset_id: dto.preset_id,
                },
            });
        });
        return { success: true, data: true }
    }

    private toIdFromFullName = async (full_name: string) => {
        const [first_name, last_name] = full_name.split(' ', 2);
        let supervisor = await this.prisma.users.findFirst({
            where: { first_name, last_name },
            select: { employee: { select: { id: true } } }
        });
        if (!supervisor) supervisor = null;
        return supervisor?.employee?.id;
    }
}