<?php
    /**
     * Membership Class
     *
     * @package Wojo Framework
     * @author wojoscripts.com
     * @copyright 2023
     * @version 5.50: Membership.php, v1.00 9/19/2023 12:30 PM Gewa Exp $
     *
     */
    if (!defined('_WOJO')) {
        die('Direct access to this location is not allowed.');
    }
    
    class Membership
    {
        const mTable = 'memberships';
        const mhTable = 'membership_history';
        
        /**
         * index
         *
         * @return void
         */
        public function index(): void
        {
            $tpl = App::View(BASEPATH . 'view/');
            $tpl->dir = 'admin/';
            $tpl->title = Language::$word->META_M_MEMBERSHIPS;
            $tpl->caption = Language::$word->META_M_MEMBERSHIPS;
            $tpl->subtitle = Language::$word->MEM_INFO;
            
            $sql = '
            SELECT m.*, (SELECT COUNT(p.membership_id)
                FROM `' . Product::xTable . '` as p
                WHERE p.membership_id = m.id) as total
              FROM `' . self::mTable . '` as m
              ORDER BY m.sorting
            ';
            $tpl->data = Database::Go()->rawQuery($sql)->run();
            $tpl->template = 'admin/membership';
        }
        
        /**
         * edit
         *
         * @param int $id
         * @return void
         */
        public function edit(int $id): void
        {
            $tpl = App::View(BASEPATH . 'view/');
            $tpl->dir = 'admin/';
            $tpl->title = Language::$word->MEM_EDIT;
            $tpl->caption = Language::$word->MEM_EDIT;
            $tpl->crumbs = ['admin', 'memberships', 'edit'];
            
            if (!$row = Database::Go()->select(self::mTable)->where('id', $id, '=')->first()->run()) {
                if (DEBUG) {
                    $tpl->error = 'Invalid ID ' . ($id) . ' detected [' . __CLASS__ . ', ln.:' . __line__ . ']';
                } else {
                    $tpl->error = Language::$word->META_ERROR;
                }
                $tpl->template = 'admin/error';
            } else {
                $tpl->data = $row;
                
                $tpl->template = 'admin/membership';
            }
        }
        
        /**
         * new
         *
         * @return void
         */
        public function new(): void
        {
            $tpl = App::View(BASEPATH . 'view/');
            $tpl->dir = 'admin/';
            $tpl->title = Language::$word->MEM_NEW;
            $tpl->caption = Language::$word->MEM_NEW;
            $tpl->subtitle = null;
            
            $tpl->template = 'admin/membership';
        }
        
        /**
         * new
         *
         * @param int $id
         * @return void
         */
        public function history(int $id): void
        {
            $tpl = App::View(BASEPATH . 'view/');
            $tpl->dir = 'admin/';
            $tpl->title = Language::$word->META_HISTORY;
            $tpl->caption = Language::$word->META_HISTORY;
            $tpl->crumbs = ['admin', Language::$word->META_MEMBERSHIPS, Language::$word->META_HISTORY];
            $tpl->subtitle = null;
            
            if (!$row = Database::Go()->select(self::mTable)->where('id', $id, '=')->first()->run()) {
                if (DEBUG) {
                    $tpl->error = 'Invalid ID ' . ($id) . ' detected [' . __CLASS__ . ', ln.:' . __line__ . ']';
                } else {
                    $tpl->error = Language::$word->META_ERROR;
                }
                $tpl->template = 'admin/error';
            } else {
                $tpl->data = $row;
                $pager = Paginator::instance();
                $pager->items_total = Database::Go()->count(Product::xTable)->where('membership_id', $id, '=')->where('status', 1, '=')->run();
                $pager->default_ipp = App::Core()->perpage;
                $pager->path = Url::url(Router::$path, '?');
                $pager->paginate();
                
                $sql = "
                SELECT p.amount, p.tax, p.coupon, p.total, p.currency, p.created, p.user_id, CONCAT(u.fname,' ',u.lname) as name
                  FROM `" . Product::xTable . '` as p
                  LEFT JOIN ' . User::mTable . ' as u ON u.id = p.user_id
                  WHERE p.membership_id = ?
                  AND p.status = ?
                  ORDER BY p.created DESC' . $pager->limit;
                $tpl->plist = Database::Go()->rawQuery($sql, array($id, 1))->run();
                $tpl->pager = $pager;
                
                $tpl->template = 'admin/membership';
            }
        }
        
        /**
         * processMembership
         *
         * @return void
         */
        public function processMembership(): void
        {
            $validate = Validator::run($_POST);
            $validate
                ->set('title', Language::$word->NAME)->required()->string()->min_len(3)->max_len(60)
                ->set('description', Language::$word->DESCRIPTION)->string()
                ->set('body', Language::$word->DESCRIPTION)->text('advanced')
                ->set('price', Language::$word->MEM_PRICE)->required()->float()
                ->set('days', Language::$word->MEM_DAYS)->required()->numeric()
                ->set('downloads', Language::$word->MEM_DOWN)->required()->numeric()
                ->set('period', Language::$word->MEM_DAYS)->required()->string()->exact_len(1)
                ->set('recurring', Language::$word->MEM_REC)->required()->numeric()
                ->set('private', Language::$word->MEM_PRIVATE)->required()->numeric()
                ->set('active', Language::$word->PUBLISHED)->required()->numeric();
            
            $safe = $validate->safe();
            $thumb = File::upload('thumb', 3145728, 'png,jpg,jpeg');
            
            if (count(Message::$msgs) === 0) {
                $data = array(
                    'title' => $safe->title,
                    'description' => $safe->description,
                    'body' => $safe->body,
                    'price' => $safe->price,
                    'days' => $safe->days,
                    'period' => $safe->period,
                    'downloads' => $safe->downloads,
                    'recurring' => $safe->recurring,
                    'private' => $safe->private,
                    'active' => $safe->active,
                );
                
                if (array_key_exists('thumb', $_FILES)) {
                    $thumbPath = UPLOADS . '/memberships/';
                    $result = File::process($thumb, $thumbPath, 'MEM_');
                    $data['thumb'] = $result['fname'];
                }
                
                (Filter::$id) ? Database::Go()->update(self::mTable, $data)->where('id', Filter::$id, '=')->run() : Database::Go()->insert(self::mTable, $data)->run();
                
                $message = Filter::$id ?
                    Message::formatSuccessMessage($data['title'], Language::$word->MEM_UPDATE_OK) :
                    Message::formatSuccessMessage($data['title'], Language::$word->MEM_ADDED_OK);
                
                Message::msgReply(Database::Go()->affected(), 'success', $message);
            } else {
                Message::msgSingleStatus();
            }
        }
        
        /**
         * is_valid
         *
         * @param string $memberships
         * @return bool
         */
        public static function is_valid(string $memberships): bool
        {
            return in_array(App::Auth()->membership_id, explode(',', $memberships));
        }
        
        /**
         * getCart
         *
         * @param int $id
         * @return mixed
         */
        public static function getCart(int $id): mixed
        {
            return Database::Go()->select(Product::cxTable)->where('user_m_id', $id, '=')->first()->run();
        }
        
        /**
         * calculateDays
         *
         * @param int $membership_id
         * @return string
         * @throws NotFoundException
         */
        public static function calculateDays(int $membership_id): string
        {
            $row = Database::Go()->select(self::mTable, array('days', 'period'))->where('id', $membership_id, '=')->first()->run();
            if ($row) {
                $diff = match ($row->period) {
                    'D' => ' day',
                    'W' => ' week',
                    'M' => ' month',
                    'Y' => ' year',
                    default => throw new NotFoundException(sprintf('The requested action "%s" don\'t match any type.', $membership_id))
                };
                $expire = Date::numberOfDays('+' . $row->days . $diff);
            } else {
                $expire = '';
            }
            return $expire;
        }
    }