<?php

require_once BASE_PATH . '/config/database.php';

class BusinessHour
{
    private PDO $db;

    public function __construct()
    {
        $this->db =
            (new Database())->connect();
    }


    /*
    |--------------------------------------------------------------------------
    | LẤY ĐỦ 7 NGÀY
    |--------------------------------------------------------------------------
    */

    public function getWeek(): array
    {
        $stmt =
            $this->db->query(
                'SELECT
                    id,
                    day_of_week,
                    open_time,
                    close_time,
                    is_open
                 FROM business_hours
                 ORDER BY day_of_week ASC'
            );

        $rows =
            $stmt->fetchAll();


        /*
         * Index theo day_of_week.
         */
        $indexed = [];

        foreach ($rows as $row) {

            $indexed[
                (int) $row['day_of_week']
            ] = $row;
        }


        /*
         * Luôn trả đủ 0 → 6.
         *
         * Nếu DB vô tình thiếu ngày nào thì Owner
         * vẫn có thể thiết lập ngày đó.
         */
        $result = [];

        foreach (range(0, 6) as $day) {

            $result[] =
                $indexed[$day]
                ?? [
                    'id' => null,
                    'day_of_week' => $day,
                    'open_time' => '08:00:00',
                    'close_time' => '18:00:00',
                    'is_open' => $day === 0
                        ? 0
                        : 1
                ];
        }

        return $result;
    }


    /*
    |--------------------------------------------------------------------------
    | GIỜ LÀM VIỆC THEO NGÀY
    |--------------------------------------------------------------------------
    */

    public function findForDate(
        string $date
    ): ?array {

        $day =
            (int) (
                new DateTimeImmutable(
                    $date
                )
            )->format('w');


        $stmt =
            $this->db->prepare(
                'SELECT *
                 FROM business_hours
                 WHERE day_of_week = :day
                 LIMIT 1'
            );


        $stmt->execute([
            'day' => $day
        ]);


        $row =
            $stmt->fetch();


        return $row ?: null;
    }


    /*
    |--------------------------------------------------------------------------
    | CẬP NHẬT 7 NGÀY
    |--------------------------------------------------------------------------
    */

    public function updateWeek(
        array $hours
    ): void {

        $this->db->beginTransaction();


        try {

            $stmt =
                $this->db->prepare(
                    'INSERT INTO business_hours (
                        day_of_week,
                        open_time,
                        close_time,
                        is_open
                    )
                    VALUES (
                        :day_of_week,
                        :open_time,
                        :close_time,
                        :is_open
                    )
                    ON DUPLICATE KEY UPDATE
                        open_time =
                            VALUES(open_time),

                        close_time =
                            VALUES(close_time),

                        is_open =
                            VALUES(is_open)'
                );


            foreach ($hours as $hour) {

                $stmt->execute([
                    'day_of_week' =>
                        (int) $hour[
                            'day_of_week'
                        ],

                    'open_time' =>
                        $hour[
                            'open_time'
                        ],

                    'close_time' =>
                        $hour[
                            'close_time'
                        ],

                    'is_open' =>
                        (int) $hour[
                            'is_open'
                        ]
                ]);
            }


            $this->db->commit();


        } catch (Throwable $e) {

            if (
                $this->db
                    ->inTransaction()
            ) {

                $this->db
                    ->rollBack();
            }


            throw $e;
        }
    }
}