<?php
require_once '_master/apiHandler.php';

class pageClass extends apiHandler
{
    public function __construct()
    {
        parent::__construct();
        $this->checkERPAccess();
    }

    /**
     * List all coupons with pagination and filtering
     */
    function index()
    {
        try {
            $allowed = ['page', 'limit', 'search', 'is_active'];
            $fields = [
                'page' => [
                    'rules' => 'integer|min:1',
                    'type'  => 'integer',
                    'default' => 1
                ],
                'limit' => [
                    'rules' => 'integer|min:1|max:100',
                    'type'  => 'integer',
                    'default' => 10
                ],
                'search' => [
                    'rules' => 'text',
                    'type'  => 'string'
                ],
                'is_active' => [
                    'rules' => 'integer|in:0,1',
                    'type'  => 'integer',
                    'default' => 1
                ],
            ];

            $request = $this->cleanRequestInputs((array)$this->getrequest, $fields, $allowed);
            if ($request['validation_errors']) {
                $this->respond(400, false, $this->trans['httpStatusCodes']['400'], null, $request['validation_errors']);
            }

            $page = isset($request['page']) ? (int) $request['page'] : 1;
            $perPage = isset($request['limit']) ? (int) $request['limit'] : 10;
            $offset = ($page - 1) * $perPage;

            $where = '1=1';
            $params = [];

            if (!empty($request['search'])) {
                $where .= ' AND (code LIKE ? OR note LIKE ?)';
                $searchTerm = '%' . $request['search'] . '%';
                $params = array_merge($params, [$searchTerm, $searchTerm]);
            }

            // if (isset($request['is_active'])) {
            //     $where .= ' AND is_active = ?';
            //     $params[] = $request['is_active'];
            // }
            // Get total count
            $total = R::count('coupons', $where, $params);

            // Get paginated results
            $coupons = R::findAll(
                'coupons',
                $where . ' ORDER BY id ASC LIMIT ?, ?',
                array_merge($params, [$offset, $perPage])
            );
            $data = [];
            foreach ($coupons as $coupon) {
                $data[] = array(
                    'id' => $coupon->id,
                    'code' => $coupon->code,
                    'discount_type' => $coupon->discount_type,
                    'discount_value' => $coupon->discount_value,
                    'start_date' => $coupon->start_date,
                    'end_date' => $coupon->end_date,
                    'is_active' => $coupon->is_active,
                    'usage_limit' => $coupon->usage_limit,
                    'per_user_limit' => $coupon->per_user_limit,
                    'minimum_order_value' => $coupon->minimum_order_value,
                    'applicable_categories' => $coupon->applicable_categories,
                    'auto_apply' => $coupon->auto_apply,
                    'note' => $coupon->note
                );
            }


            $response = [
                'data' => $data,
                'pagination' => [
                    'total' => (int)$total,
                    'limit' => $perPage,
                    'current_page' => $page,
                    'last_page' => ceil($total / $perPage)
                ]
            ];

            $this->respond(200, true, $this->trans['httpStatusCodes']['200'], null, [], $response);
        } catch (Exception $exception) {
            $this->respond(500, false, $this->trans['httpStatusCodes']['500'], $exception->getMessage(), []);
        }
    }

    /**
     * Add a new coupon
     */
    function add()
    {
        try {
            $allowed = [
                'code',
                'discount_type',
                'discount_value',
                'start_date',
                'end_date',
                'is_active',
                'usage_limit',
                'per_user_limit',
                'minimum_order_value',
                'applicable_categories',
                'auto_apply',
                'note'
            ];

            $fields = [
                'code' => [
                    'rules' => 'required|text|min:1|max:50',
                    'type'  => 'string',
                ],
                'discount_type' => [
                    'rules' => 'required|integer|min:0',
                    'type'  => 'integer',
                ],
                'discount_value' => [
                    'rules' => 'required|numeric|min:0',
                    'type'  => 'float',
                ],
                'start_date' => [
                    'rules' => 'required|date',
                    'type'  => 'string',
                ],
                'end_date' => [
                    'rules' => 'required|date',
                    'type'  => 'string',
                ],
                'is_active' => [
                    'rules' => 'integer|in:0,1',
                    'type'  => 'integer',
                    'default' => 0
                ],
                'usage_limit' => [
                    'rules' => 'integer',
                    'type'  => 'integer',
                ],
                'per_user_limit' => [
                    'rules' => 'integer',
                    'type'  => 'integer',
                ],
                'minimum_order_value' => [
                    'rules' => 'numeric',
                    'type'  => 'float',
                ],
                'applicable_categories' => [
                    'rules' => 'text',
                    'type'  => 'string',
                ],
                'auto_apply' => [
                    'rules' => 'integer|in:0,1',
                    'type'  => 'integer',
                    'default' => 0
                ],
                'note' => [
                    'rules' => 'text',
                    'type'  => 'string',
                ]
            ];

            $request = $this->cleanRequestInputs((array)$this->getrequest, $fields, $allowed);
            if ($request['validation_errors']) {
                $this->respond(400, false, $this->trans['httpStatusCodes']['400'], null, $request['validation_errors']);
            }

            // Validate dates
            $startDate = new DateTime($request['start_date']);
            $endDate = new DateTime($request['end_date']);

            if ($endDate < $startDate) {
                $this->respond(400, false, $this->trans['httpStatusCodes']['400'], 'End date must be after start date', ['end_date' => 'End date must be after start date']);
            }

            // Check if coupon code already exists
            if (R::count('coupons', 'code = ?', [$request['code']]) > 0) {
                $this->respond(409, false, $this->trans['httpStatusCodes']['409'], null, ['code' => 'This coupon code is already in use']);
            }

            $coupon = R::dispense('coupons');
            $coupon->code = $request['code'];
            $coupon->discount_type = $request['discount_type'];
            $coupon->discount_value = $request['discount_value'];
            $coupon->start_date = $request['start_date'];
            $coupon->end_date = $request['end_date'];
            $coupon->is_active = $request['is_active'];
            $coupon->usage_limit = $request['usage_limit'];
            $coupon->per_user_limit = $request['per_user_limit'];
            $coupon->minimum_order_value = $request['minimum_order_value'];
            $coupon->applicable_categories = $request['applicable_categories'];
            $coupon->auto_apply = $request['auto_apply'];
            $coupon->note = $request['note'];
            $coupon->user_id = 1; // $this->userInfo->userid
            $coupon->created_at = date('Y-m-d H:i:s');
            $coupon->updated_at = date('Y-m-d H:i:s');
            $coupon->del = 0;

            $id = R::store($coupon);
            $coupon->id = $id;

            $response = array(
                'id' => $coupon->id,
                'code' => $coupon->code,
                'discount_type' => $coupon->discount_type,
                'discount_value' => $coupon->discount_value,
                'start_date' => $coupon->start_date,
                'end_date' => $coupon->end_date,
                'is_active' => $coupon->is_active,
                'usage_limit' => $coupon->usage_limit,
                'per_user_limit' => $coupon->per_user_limit,
                'minimum_order_value' => $coupon->minimum_order_value,
                'applicable_categories' => $coupon->applicable_categories,
                'auto_apply' => $coupon->auto_apply,
                'note' => $coupon->note,
            );

            $this->respond(200, true, $this->trans['httpStatusCodes']['200'], null, [], $response);
        } catch (Exception $exception) {
            $this->respond(500, false, $this->trans['httpStatusCodes']['500'], $exception->getMessage(), []);
        }
    }

    /**
     * Get coupon by ID
     */
    function details()
    {
        try {
            $allowed = ['id'];
            $fields = [
                'id' => [
                    'rules' => 'required|integer|min:1',
                    'type'  => 'integer'
                ]
            ];

            $request = $this->cleanRequestInputs((array)$this->getrequest, $fields, $allowed);
            if ($request['validation_errors']) {
                $this->respond(400, false, $this->trans['httpStatusCodes']['400'], null, $request['validation_errors']);
            }

            $coupon = R::findOne('coupons', 'id = ?', [$request['id']]);

            if (!$coupon) {
                $this->respond(404, false, $this->trans['httpStatusCodes']['404'], null, ['id' => 'Coupon not found']);
            }

            $response = array(
                'id' => $coupon->id,
                'code' => $coupon->code,
                'discount_type' => $coupon->discount_type,
                'discount_value' => $coupon->discount_value,
                'start_date' => $coupon->start_date,
                'end_date' => $coupon->end_date,
                'is_active' => $coupon->is_active,
                'usage_limit' => $coupon->usage_limit,
                'per_user_limit' => $coupon->per_user_limit,
                'minimum_order_value' => $coupon->minimum_order_value,
                'applicable_categories' => $coupon->applicable_categories,
                'auto_apply' => $coupon->auto_apply,
                'note' => $coupon->note,
            );

            $this->respond(200, true, $this->trans['httpStatusCodes']['200'], null, [], $response);
        } catch (Exception $exception) {
            $this->respond(500, false, $this->trans['httpStatusCodes']['500'], $exception->getMessage(), []);
        }
    }

    /**
     * Update an existing coupon
     */
    function update()
    {
        try {
            $allowed = [
                'id',
                'code',
                'discount_type',
                'discount_value',
                'start_date',
                'end_date',
                'is_active',
                'usage_limit',
                'per_user_limit',
                'minimum_order_value',
                'applicable_categories',
                'auto_apply',
                'note'
            ];

            $fields = [
                'id' => [
                    'rules' => 'required|integer|min:1',
                    'type'  => 'integer'
                ],
                'code' => [
                    'rules' => 'text|min:1|max:50',
                    'type'  => 'string',
                ],
                'discount_type' => [
                    'rules' => 'integer|min:0',
                    'type'  => 'integer',
                ],
                'discount_value' => [
                    'rules' => 'numeric|min:0',
                    'type'  => 'float',
                ],
                'start_date' => [
                    'rules' => 'date',
                    'type'  => 'string',
                ],
                'end_date' => [
                    'rules' => 'date',
                    'type'  => 'string',
                ],
                'is_active' => [
                    'rules' => 'integer|in:0,1',
                    'type'  => 'integer',
                ],
                'usage_limit' => [
                    'rules' => 'integer',
                    'type'  => 'integer',
                ],
                'per_user_limit' => [
                    'rules' => 'integer',
                    'type'  => 'integer',
                ],
                'minimum_order_value' => [
                    'rules' => 'numeric',
                    'type'  => 'float',
                ],
                'applicable_categories' => [
                    'rules' => 'text',
                    'type'  => 'string',
                ],
                'auto_apply' => [
                    'rules' => 'integer|in:0,1',
                    'type'  => 'integer',
                ],
                'note' => [
                    'rules' => 'text',
                    'type'  => 'string',
                ]
            ];

            $request = $this->cleanRequestInputs((array)$this->getrequest, $fields, $allowed);
            if ($request['validation_errors']) {
                $this->respond(400, false, $this->trans['httpStatusCodes']['400'], null, $request['validation_errors']);
            }

            $coupon = R::findOne('coupons', 'id = ?', [$request['id']]);

            if (!$coupon) {
                $this->respond(404, false, $this->trans['httpStatusCodes']['404'], null, ['id' => 'Coupon not found']);
            }

            // Check if coupon code is being updated and already exists
            if (isset($request['code']) && $request['code'] !== $coupon->code) {
                if (R::count('coupons', 'code = ? AND id != ?', [$request['code'], $coupon->id]) > 0) {
                    $this->respond(409, false, $this->trans['httpStatusCodes']['409'], null, ['code' => 'This coupon code is already in use']);
                }
            }

            // Validate dates if either is being updated
            if (isset($request['start_date']) || isset($request['end_date'])) {
                $startDate = new DateTime(isset($request['start_date']) ? $request['start_date'] : $coupon->start_date);
                $endDate = new DateTime(isset($request['end_date']) ? $request['end_date'] : $coupon->end_date);

                if ($endDate < $startDate) {
                    $this->respond(400, false, $this->trans['httpStatusCodes']['400'], null, ['end_date' => 'End date must be after start date']);
                }
            }

            // Update fields that are provided in the request
            $updatableFields = [
                'code',
                'discount_type',
                'discount_value',
                'start_date',
                'end_date',
                'is_active',
                'usage_limit',
                'per_user_limit',
                'minimum_order_value',
                'applicable_categories',
                'auto_apply',
                'note'
            ];

            foreach ($updatableFields as $field) {
                if (isset($request[$field])) {
                    $coupon->$field = $request[$field];
                }
            }

            $coupon->updated_at = date('Y-m-d H:i:s');

            R::store($coupon);
            $response = array(
                'id' => $coupon->id,
                'code' => $coupon->code,
                'discount_type' => $coupon->discount_type,
                'discount_value' => $coupon->discount_value,
                'start_date' => $coupon->start_date,
                'end_date' => $coupon->end_date,
                'is_active' => $coupon->is_active,
                'usage_limit' => $coupon->usage_limit,
                'per_user_limit' => $coupon->per_user_limit,
                'minimum_order_value' => $coupon->minimum_order_value,
                'applicable_categories' => $coupon->applicable_categories,
                'auto_apply' => $coupon->auto_apply,
                'note' => $coupon->note,
            );

            $this->respond(200, true, $this->trans['httpStatusCodes']['200'], null, [], $response);
        } catch (Exception $exception) {
            $this->respond(500, false, $this->trans['httpStatusCodes']['500'], $exception->getMessage(), []);
        }
    }

    /**
     * Delete a coupon
     */
    function delete()
    {
        try {
            $allowed = ['id'];
            $fields = [
                'id' => [
                    'rules' => 'required|integer|min:1',
                    'type'  => 'integer'
                ]
            ];

            $request = $this->cleanRequestInputs((array)$this->getrequest, $fields, $allowed);
            if ($request['validation_errors']) {
                $this->respond(400, false, $this->trans['httpStatusCodes']['400'], null, $request['validation_errors']);
            }

            $coupon = R::findOne('coupons', 'id = ?', [$request['id']]);

            if (!$coupon) {
                $this->respond(404, false, $this->trans['httpStatusCodes']['404'], null, ['id' => 'Coupon not found']);
            }

            // Perform soft delete (if needed in the future)
            $coupon->is_active = 0;
            $coupon->del = 2;
            $coupon->deleted_at = date('Y-m-d H:i:s');
            R::store($coupon);

            // Or hard delete
            //R::trash($coupon);

            $this->respond(200, true, $this->trans['httpStatusCodes']['200'], null, [], ['id' => $request['id']]);
        } catch (Exception $exception) {
            $this->respond(500, false, $this->trans['httpStatusCodes']['500'], $exception->getMessage(), []);
        }
    }

    function validate()
    {
        $couponCode = isset($this->getrequest->coupon_code) ? $this->getrequest->coupon_code : '';
        $coupon = R::findOne('coupons', 'code = ?', [$couponCode]);

        if (!$coupon) {
            $this->respond(404, false, $this->trans['httpStatusCodes']['404'], null, ['couponCode' => 'Coupon not found']);
        }

        if ($coupon->is_active == 0) {
            $this->respond(400, false, $this->trans['httpStatusCodes']['400'], null, ['couponCode' => 'Coupon is not active']);
        }

        $now = new DateTime();
        $startDate = new DateTime($coupon->start_date);
        $endDate = new DateTime($coupon->end_date);

        if ($now < $startDate || $now > $endDate) {
            $this->respond(400, false, $this->trans['httpStatusCodes']['400'], null, ['couponCode' => 'Coupon is not active']);
        }

        $this->respond(200, true, $this->trans['httpStatusCodes']['200'], null, [], ['couponCode' => 'Coupon is valid']);
    }
}

require_once("_master/fireApi.php");
