<?php

namespace App\Controllers;

use App\Models\RewarderDiscountModel;
use App\Models\RewarderProductCategoryModel;
use App\Models\RewarderProductModel;
use App\Models\RewarderServiceCategoryModel;
use App\Models\RewarderServiceModel;
use App\Models\RewarderShopModel;

class RewarderDiscounts extends AdminBaseController
{
    public $title = 'Discounts';
    public $menu = 'rewarder';
    public $submenu = 'rewarder_discounts';

    public function index()
    {
        if (\is_logged() && !(hasPermissions('shop_discounts_manage') || hasPermissions('shop_discounts_view'))) {
            $this->response->redirect('/errors/denied');
        }

        $isShopkeeper = is_role('Shopkeeper');
        $shopIds = $isShopkeeper ? shopkeeper_shop_ids() : [];

        if ($isShopkeeper && !$shopIds) {
            $discounts = [];
            $shops = [];
            $lookups = [
                'PRODUCT' => [],
                'PRODUCT_CATEGORY' => [],
                'SERVICE' => [],
                'SERVICE_CATEGORY' => [],
            ];
            return view('admin/rewarder/discounts/list', compact('discounts', 'shops', 'lookups'));
        }

        $discountQuery = (new RewarderDiscountModel())->orderBy('id', 'desc');
        $discounts = $shopIds ? $discountQuery->whereIn('shop_id', $shopIds)->findAll() : $discountQuery->findAll();

        if ($shopIds) {
            $shops = array_column((new RewarderShopModel())->whereIn('id', $shopIds)->findAll(), 'name', 'id');
            $products = array_column((new RewarderProductModel())->whereIn('shop_id', $shopIds)->findAll(), 'name', 'id');
            $productCategories = array_column((new RewarderProductCategoryModel())->whereIn('shop_id', $shopIds)->findAll(), 'name', 'id');
            $services = array_column((new RewarderServiceModel())->whereIn('shop_id', $shopIds)->findAll(), 'name', 'id');
            $serviceCategories = array_column((new RewarderServiceCategoryModel())->whereIn('shop_id', $shopIds)->findAll(), 'name', 'id');
        } else {
            $shops = array_column((new RewarderShopModel())->findAll(), 'name', 'id');
            $products = array_column((new RewarderProductModel())->findAll(), 'name', 'id');
            $productCategories = array_column((new RewarderProductCategoryModel())->findAll(), 'name', 'id');
            $services = array_column((new RewarderServiceModel())->findAll(), 'name', 'id');
            $serviceCategories = array_column((new RewarderServiceCategoryModel())->findAll(), 'name', 'id');
        }

        $lookups = [
            'PRODUCT' => $products,
            'PRODUCT_CATEGORY' => $productCategories,
            'SERVICE' => $services,
            'SERVICE_CATEGORY' => $serviceCategories,
        ];

        return view('admin/rewarder/discounts/list', compact('discounts', 'shops', 'lookups'));
    }

    public function view($id)
    {
        if (\is_logged() && !(hasPermissions('shop_discounts_manage') || hasPermissions('shop_discounts_view'))) {
            $this->response->redirect('/errors/denied');
        }

        $isShopkeeper = is_role('Shopkeeper');
        $shopIds = $isShopkeeper ? shopkeeper_shop_ids() : [];
        if ($isShopkeeper && !$shopIds) {
            return redirect()->to('rewarderDiscounts')->with('notifyError', 'Shop not found');
        }

        $discountQuery = new RewarderDiscountModel();
        $discount = $shopIds ? $discountQuery->where('id', $id)->whereIn('shop_id', $shopIds)->first() : $discountQuery->getById($id);
        if (!$discount) {
            return redirect()->to('rewarderDiscounts')->with('notifyError', 'Discount not found');
        }

        $shop = (new RewarderShopModel())->getById((int) $discount->shop_id);
        $shopName = $shop ? $shop->name : '';

        if ($discount->applies_to === 'ALL') {
            $targetName = 'ALL';
        } else {
            $targetName = $discount->target_id ? ('#' . $discount->target_id) : '-';

            if ($discount->applies_to === 'PRODUCT') {
                $row = (new RewarderProductModel())->where(['id' => (int) $discount->target_id, 'shop_id' => (int) $discount->shop_id])->first();
                if ($row) {
                    $targetName = $row->name;
                }
            } elseif ($discount->applies_to === 'PRODUCT_CATEGORY') {
                $row = (new RewarderProductCategoryModel())->where(['id' => (int) $discount->target_id, 'shop_id' => (int) $discount->shop_id])->first();
                if ($row) {
                    $targetName = $row->name;
                }
            } elseif ($discount->applies_to === 'SERVICE') {
                $row = (new RewarderServiceModel())->where(['id' => (int) $discount->target_id, 'shop_id' => (int) $discount->shop_id])->first();
                if ($row) {
                    $targetName = $row->name;
                }
            } elseif ($discount->applies_to === 'SERVICE_CATEGORY') {
                $row = (new RewarderServiceCategoryModel())->where(['id' => (int) $discount->target_id, 'shop_id' => (int) $discount->shop_id])->first();
                if ($row) {
                    $targetName = $row->name;
                }
            }
        }

        return view('admin/rewarder/discounts/view', compact('discount', 'shopName', 'targetName'));
    }

    public function add()
    {
        $this->permissionCheck('shop_discounts_manage');

        $isShopkeeper = is_role('Shopkeeper');
        $shopIds = $isShopkeeper ? shopkeeper_shop_ids() : [];
        if ($isShopkeeper && !$shopIds) {
            return redirect()->to('rewarderDiscounts')->with('notifyError', 'Shop not found');
        }

        $shopsQuery = (new RewarderShopModel())->orderBy('name', 'asc');
        $shops = $shopIds ? $shopsQuery->whereIn('id', $shopIds)->findAll() : $shopsQuery->findAll();

        $productsQuery = (new RewarderProductModel())->orderBy('name', 'asc');
        $products = $shopIds ? $productsQuery->whereIn('shop_id', $shopIds)->findAll() : $productsQuery->findAll();

        $productCategoriesQuery = (new RewarderProductCategoryModel())->orderBy('name', 'asc');
        $productCategories = $shopIds ? $productCategoriesQuery->whereIn('shop_id', $shopIds)->findAll() : $productCategoriesQuery->findAll();

        $servicesQuery = (new RewarderServiceModel())->orderBy('name', 'asc');
        $services = $shopIds ? $servicesQuery->whereIn('shop_id', $shopIds)->findAll() : $servicesQuery->findAll();

        $serviceCategoriesQuery = (new RewarderServiceCategoryModel())->orderBy('name', 'asc');
        $serviceCategories = $shopIds ? $serviceCategoriesQuery->whereIn('shop_id', $shopIds)->findAll() : $serviceCategoriesQuery->findAll();

        return view('admin/rewarder/discounts/add', compact('shops', 'products', 'productCategories', 'services', 'serviceCategories'));
    }

    public function save()
    {
        $this->permissionCheck('shop_discounts_manage');
        postAllowed();

        $isShopkeeper = is_role('Shopkeeper');
        if ($isShopkeeper) {
            $shopIds = shopkeeper_shop_ids();
            if (!$shopIds) {
                return redirect()->to('rewarderDiscounts')->with('notifyError', 'Shop not found');
            }
            $shopId = (int) post('shop_id');
            if (!$shopId || !in_array($shopId, $shopIds, true)) {
                return redirect()->to('rewarderDiscounts')->with('notifyError', 'Invalid shop');
            }
        } else {
            $shopId = (int) post('shop_id');
        }

        $appliesTo = post('applies_to');
        (new RewarderDiscountModel())->create([
            'shop_id' => $shopId,
            'applies_to' => $appliesTo,
            'target_id' => $this->getTargetId($appliesTo),
            'discount_type' => post('discount_type'),
            'value' => post('value'),
            'min_amount' => post('min_amount') ?: null,
            'start_at' => post('start_at') ?: null,
            'end_at' => post('end_at') ?: null,
            '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('rewarderDiscounts')->with('notifySuccess', 'Discount created');
    }

    public function edit($id)
    {
        $this->permissionCheck('shop_discounts_manage');

        $isShopkeeper = is_role('Shopkeeper');
        $shopIds = $isShopkeeper ? shopkeeper_shop_ids() : [];
        if ($isShopkeeper && !$shopIds) {
            return redirect()->to('rewarderDiscounts')->with('notifyError', 'Shop not found');
        }

        $discountQuery = new RewarderDiscountModel();
        $discount = $shopIds ? $discountQuery->where('id', $id)->whereIn('shop_id', $shopIds)->first() : $discountQuery->getById($id);
        if (!$discount) {
            return redirect()->to('rewarderDiscounts')->with('notifyError', 'Discount not found');
        }

        $shopsQuery = (new RewarderShopModel())->orderBy('name', 'asc');
        $shops = $shopIds ? $shopsQuery->whereIn('id', $shopIds)->findAll() : $shopsQuery->findAll();

        $productsQuery = (new RewarderProductModel())->orderBy('name', 'asc');
        $products = $shopIds ? $productsQuery->whereIn('shop_id', $shopIds)->findAll() : $productsQuery->findAll();

        $productCategoriesQuery = (new RewarderProductCategoryModel())->orderBy('name', 'asc');
        $productCategories = $shopIds ? $productCategoriesQuery->whereIn('shop_id', $shopIds)->findAll() : $productCategoriesQuery->findAll();

        $servicesQuery = (new RewarderServiceModel())->orderBy('name', 'asc');
        $services = $shopIds ? $servicesQuery->whereIn('shop_id', $shopIds)->findAll() : $servicesQuery->findAll();

        $serviceCategoriesQuery = (new RewarderServiceCategoryModel())->orderBy('name', 'asc');
        $serviceCategories = $shopIds ? $serviceCategoriesQuery->whereIn('shop_id', $shopIds)->findAll() : $serviceCategoriesQuery->findAll();

        return view('admin/rewarder/discounts/edit', compact('discount', 'shops', 'products', 'productCategories', 'services', 'serviceCategories'));
    }

    public function update($id)
    {
        $this->permissionCheck('shop_discounts_manage');
        postAllowed();

        $isShopkeeper = is_role('Shopkeeper');
        if ($isShopkeeper) {
            $shopIds = shopkeeper_shop_ids();
            if (!$shopIds) {
                return redirect()->to('rewarderDiscounts')->with('notifyError', 'Shop not found');
            }
            $shopId = (int) post('shop_id');
            if (!$shopId || !in_array($shopId, $shopIds, true)) {
                return redirect()->to('rewarderDiscounts')->with('notifyError', 'Invalid shop');
            }
            $discount = (new RewarderDiscountModel())->where('id', $id)->whereIn('shop_id', $shopIds)->first();
            if (!$discount) {
                return redirect()->to('rewarderDiscounts')->with('notifyError', 'Discount not found');
            }
        } else {
            $shopId = (int) post('shop_id');
        }

        $appliesTo = post('applies_to');
        if ($isShopkeeper) {
            (new RewarderDiscountModel())->update($id, [
                'shop_id' => $shopId,
                'applies_to' => $appliesTo,
                'target_id' => $this->getTargetId($appliesTo),
                'discount_type' => post('discount_type'),
                'value' => post('value'),
                'min_amount' => post('min_amount') ?: null,
                'start_at' => post('start_at') ?: null,
                'end_at' => post('end_at') ?: null,
                'status' => (int) post('status'),
                'updated_at' => date('Y-m-d H:i:s'),
            ]);
        } else {
            (new RewarderDiscountModel())->update($id, [
                'shop_id' => $shopId,
                'applies_to' => $appliesTo,
                'target_id' => $this->getTargetId($appliesTo),
                'discount_type' => post('discount_type'),
                'value' => post('value'),
                'min_amount' => post('min_amount') ?: null,
                'start_at' => post('start_at') ?: null,
                'end_at' => post('end_at') ?: null,
                'status' => (int) post('status'),
                'updated_at' => date('Y-m-d H:i:s'),
            ]);
        }

        return redirect()->to('rewarderDiscounts')->with('notifySuccess', 'Discount updated');
    }

    public function delete($id)
    {
        $this->permissionCheck('shop_discounts_manage');

        if (is_role('Shopkeeper')) {
            $shopIds = shopkeeper_shop_ids();
            if (!$shopIds) {
                return redirect()->to('rewarderDiscounts')->with('notifyError', 'Shop not found');
            }
            (new RewarderDiscountModel())->where('id', $id)->whereIn('shop_id', $shopIds)->delete();
        } else {
            (new RewarderDiscountModel())->delete($id);
        }
        return redirect()->to('rewarderDiscounts')->with('notifySuccess', 'Discount 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;
    }
}

