<?php

namespace App\Controllers\Api\Admin;

use App\Models\RewarderServiceModel;
use CodeIgniter\HTTP\ResponseInterface;

class Services extends BaseAdminApiController
{
    public function index(): ResponseInterface
    {
        if ($resp = $this->requirePermission(['shop_services_manage', 'shop_services_view'])) {
            return $resp;
        }

        $q = db_connect()->table('rewarder_services s')
            ->select('s.*, sh.name as shop_name, c.name as category_name')
            ->join('rewarder_shops sh', 'sh.id = s.shop_id', 'left')
            ->join('rewarder_service_categories c', 'c.id = s.category_id', 'left')
            ->orderBy('s.id', 'desc');

        $shopId = $this->isShopkeeper() ? $this->shopkeeperShopId() : null;
        if ($shopId) {
            $q->where('s.shop_id', (int) $shopId);
        } else {
            $filterShopId = $this->request->getGet('shop_id');
            if ($filterShopId !== null && $filterShopId !== '') {
                $q->where('s.shop_id', (int) $filterShopId);
            }
        }

        $filterCategoryId = $this->request->getGet('category_id');
        if ($filterCategoryId !== null && $filterCategoryId !== '') {
            $q->where('s.category_id', (int) $filterCategoryId);
        }

        $rows = $q->get()->getResult();
        foreach ($rows as $r) {
            $r->image_url = !empty($r->img_type) ? urlUpload('services/' . $r->id . '.' . $r->img_type, true) : null;
        }

        return $this->ok($rows);
    }

    public function show(int $id): ResponseInterface
    {
        if ($resp = $this->requirePermission(['shop_services_manage', 'shop_services_view'])) {
            return $resp;
        }

        $q = db_connect()->table('rewarder_services s')
            ->select('s.*, sh.name as shop_name, c.name as category_name')
            ->join('rewarder_shops sh', 'sh.id = s.shop_id', 'left')
            ->join('rewarder_service_categories c', 'c.id = s.category_id', 'left')
            ->where('s.id', $id);

        $shopId = $this->isShopkeeper() ? $this->shopkeeperShopId() : null;
        if ($shopId) {
            $q->where('s.shop_id', (int) $shopId);
        }

        $row = $q->get()->getRow();
        if (!$row) {
            return $this->fail('Not found', 404);
        }
        $row->image_url = !empty($row->img_type) ? urlUpload('services/' . $row->id . '.' . $row->img_type, true) : null;

        return $this->ok($row);
    }

    public function create(): ResponseInterface
    {
        if ($resp = $this->requirePermission('shop_services_manage')) {
            return $resp;
        }

        $m = new RewarderServiceModel();

        $name = trim((string) $this->input('name', ''));
        if ($name === '') {
            return $this->fail('Validation failed', 422, ['name' => 'Name is required']);
        }

        $shopId = $this->isShopkeeper() ? $this->shopkeeperShopId() : (int) $this->input('shop_id', 0);
        if (!$shopId) {
            return $this->fail('Validation failed', 422, ['shop_id' => 'Shop is required']);
        }

        if (!$this->isShopkeeper()) {
            $shopExists = db_connect()->table('rewarder_shops')->where('id', (int) $shopId)->countAllResults() > 0;
            if (!$shopExists) {
                return $this->fail('Validation failed', 422, ['shop_id' => 'Shop not found']);
            }
        }

        $rawCategoryId = $this->input('category_id');
        $categoryId = ($rawCategoryId !== null && $rawCategoryId !== '') ? (int) $rawCategoryId : null;
        if ($categoryId !== null) {
            $cat = db_connect()->table('rewarder_service_categories')
                ->where(['id' => (int) $categoryId, 'shop_id' => (int) $shopId])
                ->get()
                ->getRow();
            if (!$cat) {
                return $this->fail('Validation failed', 422, ['category_id' => 'Invalid category for this shop']);
            }
        }

        $rawPrice = $this->input('price', 0);
        if ($rawPrice === '' || !is_numeric($rawPrice)) {
            return $this->fail('Validation failed', 422, ['price' => 'Price must be a number']);
        }
        $price = (float) $rawPrice;
        if ($price < 0) {
            return $this->fail('Validation failed', 422, ['price' => 'Price must be >= 0']);
        }

        $status = (int) $this->input('status', 1);
        if (!in_array($status, [0, 1], true)) {
            return $this->fail('Validation failed', 422, ['status' => 'Invalid status']);
        }

        $now = date('Y-m-d H:i:s');
        $id = $m->create([
            'shop_id' => (int) $shopId,
            'category_id' => $categoryId,
            'name' => $name,
            'price' => $price,
            'status' => $status,
            'created_at' => $now,
            'updated_at' => $now,
        ]);

        $ext = uploadPublicImage('image', 'services', (string) $id);
        if ($ext) {
            $m->update($id, [
                'img_type' => $ext,
                'updated_at' => date('Y-m-d H:i:s'),
            ]);
        }

        $row = $m->getById($id);
        if ($row) {
            $row->image_url = !empty($row->img_type) ? urlUpload('services/' . $row->id . '.' . $row->img_type, true) : null;
        }

        return $this->ok($row, [], 201);
    }

    public function update(int $id): ResponseInterface
    {
        if ($resp = $this->requirePermission('shop_services_manage')) {
            return $resp;
        }

        $m = new RewarderServiceModel();
        $existing = $m->getById($id);
        if (!$existing) {
            return $this->fail('Not found', 404);
        }

        $shopId = $this->isShopkeeper() ? $this->shopkeeperShopId() : (int) $this->input('shop_id', 0);
        if (!$shopId) {
            return $this->fail('Validation failed', 422, ['shop_id' => 'Shop is required']);
        }

        if ($this->isShopkeeper()) {
            $exists = $m->where(['id' => $id, 'shop_id' => (int) $shopId])->first();
            if (!$exists) {
                return $this->fail('Not found', 404);
            }
        } else {
            $shopExists = db_connect()->table('rewarder_shops')->where('id', (int) $shopId)->countAllResults() > 0;
            if (!$shopExists) {
                return $this->fail('Validation failed', 422, ['shop_id' => 'Shop not found']);
            }
        }

        $name = trim((string) $this->input('name', ''));
        if ($name === '') {
            return $this->fail('Validation failed', 422, ['name' => 'Name is required']);
        }

        $rawCategoryId = $this->input('category_id');
        $categoryId = ($rawCategoryId !== null && $rawCategoryId !== '') ? (int) $rawCategoryId : null;
        if ($categoryId !== null) {
            $cat = db_connect()->table('rewarder_service_categories')
                ->where(['id' => (int) $categoryId, 'shop_id' => (int) $shopId])
                ->get()
                ->getRow();
            if (!$cat) {
                return $this->fail('Validation failed', 422, ['category_id' => 'Invalid category for this shop']);
            }
        }

        $rawPrice = $this->input('price', 0);
        if ($rawPrice === '' || !is_numeric($rawPrice)) {
            return $this->fail('Validation failed', 422, ['price' => 'Price must be a number']);
        }
        $price = (float) $rawPrice;
        if ($price < 0) {
            return $this->fail('Validation failed', 422, ['price' => 'Price must be >= 0']);
        }

        $status = (int) $this->input('status', 1);
        if (!in_array($status, [0, 1], true)) {
            return $this->fail('Validation failed', 422, ['status' => 'Invalid status']);
        }

        $data = [
            'shop_id' => (int) $shopId,
            'category_id' => $categoryId,
            'name' => $name,
            'price' => $price,
            'status' => $status,
            'updated_at' => date('Y-m-d H:i:s'),
        ];

        $ext = uploadPublicImage('image', 'services', (string) $id);
        if ($ext) {
            $data['img_type'] = $ext;
        }

        if ($this->isShopkeeper()) {
            $m->where(['id' => $id, 'shop_id' => (int) $shopId])->set($data)->update();
        } else {
            $m->update($id, $data);
        }

        $row = $m->getById($id);
        if ($row) {
            $row->image_url = !empty($row->img_type) ? urlUpload('services/' . $row->id . '.' . $row->img_type, true) : null;
        }

        return $this->ok($row);
    }

    public function delete(int $id): ResponseInterface
    {
        if ($resp = $this->requirePermission('shop_services_manage')) {
            return $resp;
        }

        $m = new RewarderServiceModel();
        if ($this->isShopkeeper()) {
            $shopId = $this->shopkeeperShopId();
            if (!$shopId) {
                return $this->fail('Shop not found', 422);
            }
            $m->where(['id' => $id, 'shop_id' => (int) $shopId])->delete();
        } else {
            $m->delete($id);
        }

        return $this->ok(true);
    }
}
