<?php
/*
 * Copyright (c) 2026 AltumCode (https://altumcode.com/)
 *
 * This software is licensed exclusively by AltumCode and is sold only via https://altumcode.com/.
 * Unauthorized distribution, modification, or use of this software without a valid license is not permitted and may be subject to applicable legal actions.
 *
 * 🌍 View all other existing AltumCode projects via https://altumcode.com/
 * 📧 Get in touch for support or general queries via https://altumcode.com/contact
 * 📤 Download the latest version via https://altumcode.com/downloads
 *
 * 🐦 X/Twitter: https://x.com/AltumCode
 * 📘 Facebook: https://facebook.com/altumcode
 * 📸 Instagram: https://instagram.com/altumcode
 */

namespace Altum\Controllers;

use Altum\Alerts;
use Altum\Meta;
use Altum\Models\User;
use Altum\Title;

defined('ALTUMCODE') || die();

class Store extends Controller {
    public $store = null;
    public $store_user = null;
    public $has_access = null;
    public $is_preview = null;

    public function index() {

        $this->init();

        /* Check if the password form is submitted */
        if(!$this->has_access && !empty($_POST)) {
            $_POST['password'] = mb_substr($_POST['password'] ?? '', 0, 64);

            /* Check for any errors */
            if(!\Altum\Csrf::check()) {
                Alerts::add_error(l('global.error_message.invalid_csrf_token'));
            }

            if(!password_verify($_POST['password'], $this->store->password)) {
                Alerts::add_field_error('password', l('s_store.password.error_message'));
            }

            if(!Alerts::has_field_errors() && !Alerts::has_errors()) {

                /* Set a cookie */
                setcookie('store_password_' . $this->store->store_id, $this->store->password, time()+60*60*24*30);

                header('Location: ' . $this->store->full_url); die();

            }

        }

        /* Display the password form */
        if(!$this->has_access) {

            /* Set a custom title */
            Title::set(l('s_store.password.title'));

            /* Main View */
            $data = [
                'store' => $this->store,
            ];

            $view = new \Altum\View('s/store/' . $this->store->theme . '/password', (array) $this);

        }

        /* No password or access granted */
        else {

            $this->create_statistics($this->store->store_id);

            /* Calculate open hours */
            $now = (new \DateTime())->setTimezone(new \DateTimeZone($this->store->timezone));
            $day = mb_strtolower($now->format('N'));

            /* Get the available items */
            $menus = (new \Altum\Models\Menu())->get_menus_by_store_id($this->store->store_id);

            /* Set a custom title */
            if($this->store->settings->title) {
                Title::set($this->store->settings->title, true);
            } else {
                Title::set($this->store->name);
            }

            /* Set the meta tags */
            if($this->store->settings->meta_description) {
                Meta::set_description(string_truncate($this->store->settings->meta_description, 160));
                Meta::set_social_description(string_truncate($this->store->settings->meta_description, 160));
            } else {
                Meta::set_description(string_truncate($this->store->description, 160));
                Meta::set_social_description(string_truncate($this->store->description, 160));
            }
            if($this->store->settings->meta_keywords) {
                Meta::set_keywords(string_truncate($this->store->settings->meta_keywords, 160));
            }
            Meta::set_social_url($this->store->full_url);
            Meta::set_social_title($this->store->settings->title ?? $this->store->name);
            Meta::set_social_image(!empty($this->store->opengraph) ? \Altum\Uploads::get_full_url('store_opengraph') . $this->store->opengraph : null);
            Meta::set_canonical_url($this->store->full_url);

            /* Prepare the header */
            $view = new \Altum\View('s/partials/header', (array) $this);
            $this->add_view_content('header', $view->run(['store' => $this->store]));

            /* Main View */
            $data = [
                'store' => $this->store,
                'store_user' => $this->store_user,
                'menus' => $menus,

                'day' => $day
            ];

            $view = new \Altum\View('s/store/' . $this->store->theme . '/index', (array) $this);
        }

        $this->add_view_content('content', $view->run($data));
    }

    public function init() {

		/* Detect if access to url comes from id linking or url alias */
		if(isset(\Altum\Router::$data['store'])) {
			$store = $this->store = \Altum\Router::$data['store'];
		} else {

			if(isset($_GET['store_id'])) {
				$store_id = (int) $_GET['store_id'];
				$store = $this->store = db()->where('store_id', $store_id)->getOne('stores');
                if($store) $store->full_url = SITE_URL . 's/store?store_id=' . $store->store_id;
			}

		}

		/* Is preview */
		if(isset($_GET['preview']) && $_GET['preview'] == md5($this->store->user_id)) {
			$this->is_preview = true;
		}

		/* Make sure the vcard is active */
		if(!$this->store->is_enabled && !$this->is_preview) {
			throw_404();
		}

        $this->store_user = (new User())->get_user_by_user_id($this->store->user_id);

        /* Make sure to check if the user is active */
        if($this->store_user->status != 1) {
            throw_404();
        }

        /* Process the plan of the user */
        (new User())->process_user_plan_expiration_by_user($this->store_user);

        /* Check if the user has access to the store */
        $has_access = !$store->password || ($store->password && isset($_COOKIE['store_password_' . $store->store_id]) && $_COOKIE['store_password_' . $store->store_id] == $store->password);

        /* Do not let the user have password protection if the plan doesnt allow it */
        if(!$this->store_user->plan_settings->password_protection_is_enabled || $this->is_preview) {
            $has_access = true;
        }

        $this->has_access = $has_access;

        /* Parse some details */
        foreach(['settings', 'details', 'socials', 'payment_processors', 'business', 'ordering'] as $key) {
            $store->{$key} = json_decode($store->{$key} ?? '');
        }

        $this->store->cart_is_enabled = $this->store_user->plan_settings->ordering_is_enabled && ($this->store->ordering->on_premise_is_enabled || $this->store->ordering->takeaway_is_enabled || $this->store->ordering->delivery_is_enabled);

        /* Set the default language of the user */
        \Altum\Language::set_by_name($this->store_user->language, false);
    }

    /* Insert statistics log */
    public function create_statistics($store_id = null, $menu_id = null, $category_id = null, $item_id = null) {

        $cookie_name = 's_statistics_' . $store_id . '_' . $menu_id . '_' . $category_id . '_' . $item_id;

        if(isset($_COOKIE[$cookie_name]) && (int) $_COOKIE[$cookie_name] >= 3) {
            return;
        }

        if(!$this->store_user->plan_settings->analytics_is_enabled) {
            return;
        }

        /* Detect extra details about the user */
        $whichbrowser = get_whichbrowser();

        /* Do not track bots */
        if($whichbrowser->device->type == 'bot') {
            return;
        }

        /* Ignore excluded ips */
        $excluded_ips = array_flip($this->store_user->preferences->excluded_ips ?? []);
        if(isset($excluded_ips[get_ip()])) return;

        /* Detect extra details about the user */
        $browser_name = $whichbrowser->browser->name ?? null;
        $os_name = $whichbrowser->os->name ?? null;
        $browser_language = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2) : null;
        $device_type = get_this_device_type();
        $is_unique = isset($_COOKIE[$cookie_name]) ? 0 : 1;

        /* Detect the location */
        try {
            $maxmind = (get_maxmind_reader_city())->get(get_ip());
        } catch(\Exception $exception) {
            /* :) */
        }
        $continent_code = isset($maxmind) && isset($maxmind['continent']) ? $maxmind['continent']['code'] : null;
        $country_code = isset($maxmind) && isset($maxmind['country']) ? $maxmind['country']['iso_code'] : null;
        $city_name = isset($maxmind) && isset($maxmind['city']) ? $maxmind['city']['names']['en'] : null;

        /* Process referrer */
        $referrer = isset($_SERVER['HTTP_REFERER']) ? parse_url($_SERVER['HTTP_REFERER']) : null;

        if(!isset($referrer)) {
            $referrer = [
                'host' => null,
                'path' => null
            ];
        }

        /* Check if referrer actually comes from the QR code */
        if(isset($_GET['referrer']) && $_GET['referrer'] == 'qr') {
            $referrer = [
                'host' => 'qr',
                'path' => null
            ];
        }

        $utm_source = input_clean($_GET['utm_source'] ?? null);
        $utm_medium = input_clean($_GET['utm_medium'] ?? null);
        $utm_campaign = input_clean($_GET['utm_campaign'] ?? null);

        /* Insert or update the log */
        db()->insert('statistics', [
            'store_id' => $store_id,
            'menu_id' => $menu_id,
            'category_id' => $category_id,
            'item_id' => $item_id,
            'continent_code' => $continent_code,
            'country_code' => $country_code,
            'city_name' => $city_name,
            'os_name' => $os_name,
            'browser_name' => $browser_name,
            'referrer_host' => $referrer['host'],
            'referrer_path' => $referrer['path'],
            'device_type' => $device_type,
            'browser_language' => $browser_language,
            'utm_source' => $utm_source,
            'utm_medium' => $utm_medium,
            'utm_campaign' => $utm_campaign,
            'is_unique' => $is_unique,
            'datetime' => get_date(),
        ]);

        /* Add the unique hit to the store table as well */
        if($store_id && !$menu_id && !$category_id && !$item_id) db()->where('store_id', $store_id)->update('stores', ['pageviews' => db()->inc()]);
        if($menu_id && !$category_id && !$item_id) db()->where('menu_id', $menu_id)->update('menus', ['pageviews' => db()->inc()]);
        if($category_id && !$item_id) db()->where('category_id', $category_id)->update('categories', ['pageviews' => db()->inc()]);
        if($item_id) db()->where('item_id', $item_id)->update('items', ['pageviews' => db()->inc()]);

        /* Set cookie to try and avoid multiple entrances */
        $cookie_new_value = isset($_COOKIE[$cookie_name]) ? (int) $_COOKIE[$cookie_name] + 1 : 0;
        setcookie($cookie_name, (int) $cookie_new_value, time()+60*60*24*1);
    }

}
