<?php

namespace App\Controllers\Frontend\Shopkeeper;

use App\Controllers\FrontendBaseController;
use App\Models\RewarderProductCategoryModel;
use App\Models\RewarderProductModel;
use App\Models\RewarderRewardRuleModel;
use App\Models\RewarderServiceCategoryModel;
use App\Models\RewarderServiceModel;

class Rewards extends FrontendBaseController
{
    public $title = 'Reward Rules';
    public $menu = 'shopkeeper';
    public $submenu = 'rewards';

    public function index()
    {
        if (!is_role('Shopkeeper')) {
            return redirect()->to(landing_url());
        }
        $this->permissionCheck('shop_rewards_manage');

        $shopId = shopkeeper_shop_id();
        $rules = $shopId ? (new RewarderRewardRuleModel())->where('shop_id', $shopId)->orderBy('id', 'desc')->findAll() : [];

        $products = $shopId ? (new RewarderProductModel())->where('shop_id', $shopId)->findAll() : [];
        $productCategories = $shopId ? (new RewarderProductCategoryModel())->where('shop_id', $shopId)->findAll() : [];
        $services = $shopId ? (new RewarderServiceModel())->where('shop_id', $shopId)->findAll() : [];
        $serviceCategories = $shopId ? (new RewarderServiceCategoryModel())->where('shop_id', $shopId)->findAll() : [];

        $lookups = [
            'PRODUCT' => array_column(array_map(fn($p) => ['id' => $p->id, 'name' => $p->name], $products), 'name', 'id'),
            'PRODUCT_CATEGORY' => array_column(array_map(fn($c) => ['id' => $c->id, 'name' => $c->name], $productCategories), 'name', 'id'),
            'SERVICE' => array_column(array_map(fn($s) => ['id' => $s->id, 'name' => $s->name], $services), 'name', 'id'),
            'SERVICE_CATEGORY' => array_column(array_map(fn($c) => ['id' => $c->id, 'name' => $c->name], $serviceCategories), 'name', 'id'),
        ];

        return view('frontend/shopkeeper/rewards/list', compact('rules', 'lookups'));
    }

    public function add()
    {
        if (!is_role('Shopkeeper')) {
            return redirect()->to(landing_url());
        }
        $this->permissionCheck('shop_rewards_manage');

        $shopId = shopkeeper_shop_id();
        $products = (new RewarderProductModel())->where('shop_id', $shopId)->orderBy('name', 'asc')->findAll();
        $productCategories = (new RewarderProductCategoryModel())->where('shop_id', $shopId)->orderBy('name', 'asc')->findAll();
        $services = (new RewarderServiceModel())->where('shop_id', $shopId)->orderBy('name', 'asc')->findAll();
        $serviceCategories = (new RewarderServiceCategoryModel())->where('shop_id', $shopId)->orderBy('name', 'asc')->findAll();

        return view('frontend/shopkeeper/rewards/add', compact('products', 'productCategories', 'services', 'serviceCategories'));
    }

    public function save()
    {
        if (!is_role('Shopkeeper')) {
            return redirect()->to(landing_url());
        }
        $this->permissionCheck('shop_rewards_manage');
        postAllowed();

        $shopId = shopkeeper_shop_id();
        $appliesTo = post('applies_to');
        $targetId = $this->getTargetId($appliesTo);
        $minBillValue = post('min_bill_value') === null || post('min_bill_value') === '' ? 0 : (float) post('min_bill_value');
        $maxBillValue = post('max_bill_value') === null || post('max_bill_value') === '' ? 0 : (float) post('max_bill_value');
        $rewardPointsExpireDays = post('reward_points_expire_days') === null || post('reward_points_expire_days') === '' ? 0 : (int) post('reward_points_expire_days');
        $minBillValue = max(0, $minBillValue);
        $maxBillValue = max(0, $maxBillValue);
        $rewardPointsExpireDays = max(0, $rewardPointsExpireDays);
        if ($minBillValue > 0 && $maxBillValue > 0 && $maxBillValue < $minBillValue) {
            return redirect()->back()->withInput()->with('notifyError', 'Max bill value must be greater than or equal to min bill value (or 0 for no limit).');
        }

        (new RewarderRewardRuleModel())->create([
            'shop_id' => $shopId,
            'applies_to' => $appliesTo,
            'target_id' => $targetId,
            'min_bill_value' => $minBillValue,
            'max_bill_value' => $maxBillValue,
            'reward_points_expire_days' => $rewardPointsExpireDays,
            'points_type' => post('points_type'),
            'value' => post('value'),
            'status' => (int) post('status'),
            'created_by' => logged('id'),
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s'),
        ]);

        return redirect()->to('shopkeeper/rewards')->with('notifySuccess', 'Reward rule created');
    }

    public function edit($id)
    {
        if (!is_role('Shopkeeper')) {
            return redirect()->to(landing_url());
        }
        $this->permissionCheck('shop_rewards_manage');

        $shopId = shopkeeper_shop_id();
        $rule = (new RewarderRewardRuleModel())->where(['id' => $id, 'shop_id' => $shopId])->first();
        if (!$rule) {
            return redirect()->to('shopkeeper/rewards')->with('notifyError', 'Rule not found');
        }

        $products = (new RewarderProductModel())->where('shop_id', $shopId)->orderBy('name', 'asc')->findAll();
        $productCategories = (new RewarderProductCategoryModel())->where('shop_id', $shopId)->orderBy('name', 'asc')->findAll();
        $services = (new RewarderServiceModel())->where('shop_id', $shopId)->orderBy('name', 'asc')->findAll();
        $serviceCategories = (new RewarderServiceCategoryModel())->where('shop_id', $shopId)->orderBy('name', 'asc')->findAll();

        return view('frontend/shopkeeper/rewards/edit', compact('rule', 'products', 'productCategories', 'services', 'serviceCategories'));
    }

    public function update($id)
    {
        if (!is_role('Shopkeeper')) {
            return redirect()->to(landing_url());
        }
        $this->permissionCheck('shop_rewards_manage');
        postAllowed();

        $shopId = shopkeeper_shop_id();
        $appliesTo = post('applies_to');
        $targetId = $this->getTargetId($appliesTo);
        $minBillValue = post('min_bill_value') === null || post('min_bill_value') === '' ? 0 : (float) post('min_bill_value');
        $maxBillValue = post('max_bill_value') === null || post('max_bill_value') === '' ? 0 : (float) post('max_bill_value');
        $rewardPointsExpireDays = post('reward_points_expire_days') === null || post('reward_points_expire_days') === '' ? 0 : (int) post('reward_points_expire_days');
        $minBillValue = max(0, $minBillValue);
        $maxBillValue = max(0, $maxBillValue);
        $rewardPointsExpireDays = max(0, $rewardPointsExpireDays);
        if ($minBillValue > 0 && $maxBillValue > 0 && $maxBillValue < $minBillValue) {
            return redirect()->back()->withInput()->with('notifyError', 'Max bill value must be greater than or equal to min bill value (or 0 for no limit).');
        }

        (new RewarderRewardRuleModel())->where(['id' => $id, 'shop_id' => $shopId])->set([
            'applies_to' => $appliesTo,
            'target_id' => $targetId,
            'min_bill_value' => $minBillValue,
            'max_bill_value' => $maxBillValue,
            'reward_points_expire_days' => $rewardPointsExpireDays,
            'points_type' => post('points_type'),
            'value' => post('value'),
            'status' => (int) post('status'),
            'updated_at' => date('Y-m-d H:i:s'),
        ])->update();

        return redirect()->to('shopkeeper/rewards')->with('notifySuccess', 'Reward rule updated');
    }

    public function delete($id)
    {
        if (!is_role('Shopkeeper')) {
            return redirect()->to(landing_url());
        }
        $this->permissionCheck('shop_rewards_manage');

        $shopId = shopkeeper_shop_id();
        (new RewarderRewardRuleModel())->where(['id' => $id, 'shop_id' => $shopId])->delete();
        return redirect()->to('shopkeeper/rewards')->with('notifySuccess', 'Reward rule deleted');
    }

    private function getTargetId($appliesTo)
    {
        if ($appliesTo === 'PRODUCT') {
            return post('product_id') ?: null;
        }
        if ($appliesTo === 'PRODUCT_CATEGORY') {
            return post('product_category_id') ?: null;
        }
        if ($appliesTo === 'SERVICE') {
            return post('service_id') ?: null;
        }
        if ($appliesTo === 'SERVICE_CATEGORY') {
            return post('service_category_id') ?: null;
        }
        return null;
    }
}

