import { Injectable } from '@nestjs/common'
import { PrismaService } from '../prisma/prisma.service'
import { CreateBranchDto } from './dto/create-branch.dto'
import { UpdateBranchDto } from './dto/update-branch.dto'
import { BootstrapTableRequestDto } from '../commons/dto/bootstrap-table-request.dto'
import { BootstrapTableResponseDto } from '../commons/dto/bootstrap-table-response.dto'
import { Prisma } from 'generated/prisma/client'
import { buildWhereClause } from 'src/commons/utils/prisma-query-builder'

@Injectable()
export class BranchService {
    constructor(private prisma: PrismaService) { }

    create(data: CreateBranchDto) {
        return this.prisma.branch.create({
            data: {
                ...data,
                beginEffective: new Date(data.beginEffective),
                endEffective: data.endEffective ? new Date(data.endEffective) : null,
            },
        })
    }

    async findAll(query: BootstrapTableRequestDto) {
        const allowedFilters = {
            code: 'string',
            name: 'string',
            address: 'string',
            beginEffective: 'date',
            endEffective: 'date',
        } as const

        const where = buildWhereClause(
            query,
            allowedFilters,
            ['code', 'name', 'address'],
        )

        const allowedSortColumns = [
            'code',
            'name',
            'beginEffective',
            'endEffective',
            'createdAt',
        ]

        const orderBy: Prisma.BranchOrderByWithRelationInput = {}

        if (query.sort && allowedSortColumns.includes(query.sort)) {
            orderBy[query.sort] = query.sortOrder
        } else {
            orderBy.createdAt = 'desc'
        }

        const [total, rows] = await this.prisma.$transaction([
            this.prisma.branch.count({ where }),
            this.prisma.branch.findMany({
                where,
                skip: query.skip,
                take: query.take,
                orderBy,
            }),
        ])

        return new BootstrapTableResponseDto(total, rows)
    }

    findOne(id: string) {
        return this.prisma.branch.findUnique({
            where: { id },
            include: {
                users: {
                    include: {
                        user: true,
                    },
                },
            },
        })
    }

    update(id: string, data: UpdateBranchDto) {
        return this.prisma.branch.update({
            where: { id },
            data: {
                ...data,
                beginEffective: data.beginEffective
                    ? new Date(data.beginEffective)
                    : undefined,
                endEffective: data.endEffective
                    ? new Date(data.endEffective)
                    : undefined,
            },
        })
    }

    remove(id: string) {
        return this.prisma.branch.delete({
            where: { id },
        })
    }
}