<?php
/**
 * article and page model
 *
 * @package EMLOG
 * @link https://www.emlog.net
 */

class Stock_Model {

    private $db;
    private $Parsedown;
    private $table;
    private $table_user;
    private $table_sort;

    public function __construct() {
        $this->db = Database::getInstance();
        $this->table = DB_PREFIX . 'stock';
        $this->table_user = DB_PREFIX . 'user';
        $this->table_sort = DB_PREFIX . 'sort';
        $this->Parsedown = new Parsedown();
        $this->Parsedown->setBreaksEnabled(true); //automatic line wrapping
    }

    /**
     * 删除库存记录
     */
    public function deleteStock($where){
        $sql = "DELETE FROM $this->table where $where";
        $this->db->query($sql);
    }

    /**
     * 创建主订单
     */
    public function addOrder($productData) {
        $kItem = $dItem = [];
        foreach ($productData as $key => $data) {
            $kItem[] = $key;
            $dItem[] = $data;
        }
        $field = implode(',', $kItem);
        $values = "'" . implode("','", $dItem) . "'";
        $this->db->query("INSERT INTO $this->table ($field) VALUES ($values)");
        return $this->db->insert_id();
    }
    /**
     * 添加库存
     */
    public function addStock($insertData) {
        $kItem = $dItem = [];
        foreach ($insertData as $key => $data) {
            $kItem[] = $key;
            $dItem[] = $data;
        }
        $field = implode(',', $kItem);
        $values = "'" . implode("','", $dItem) . "'";
        $this->db->query("INSERT INTO $this->table ($field) VALUES ($values)");
        return true;
    }

    public function updateStock($update, $goods_id, $sku) {
        $sets = [];
        foreach ($update as $key => $val) {
            $sets[] = "`$key` = '$val'";
        }
        $sql = "UPDATE " . DB_PREFIX . "stock SET " . implode(',', $sets) . " WHERE goods_id = $goods_id and sku='{$sku}'";
        return $this->db->query($sql);
    }
    public function isStock($goods_id, $sku){
        $sql = "SELECT * FROM " . DB_PREFIX . "stock where goods_id=$goods_id and sku='{$sku}'";
        $stock = $this->db->once_fetch_array($sql);
        if($stock){
            return true;
        }else{
            return false;
        }
    }

    /**
     * 获取产品sku信息
     */
    public function getSku($goods_id, $sku){
        $sql = "SELECT * FROM " . DB_PREFIX . "goods_sku where goods_id={$goods_id} and specification='{$sku}'";
//        echo $sql;die;
        $res = $this->db->query($sql);
        $row = $this->db->fetch_array($res);
        $row['price'] /= 100;
        return $row;
    }

    /**
     * 获取sku的规格属性
     */
    public function getSpecification($specification_ids){
        if (empty($specification_ids)) {
            return false;
        }
        $data = [];
        foreach($specification_ids as $val){
            $sql = "SELECT * FROM " . DB_PREFIX . "sku_attr where id={$val}";
            $res = $this->db->query($sql);
            $row = $this->db->fetch_array($res);
            $data[] = $row;
        }
//        d($data);
        return $data;
    }

    /**
     * 获取sku的规格属性值
     */
    public function getSpecificationValue($specification) {
        if (empty($specification)) {
            return false;
        }
        $specification = explode('-', $specification);
        $data = [];
        foreach($specification as $val){
            $sql = "SELECT * FROM " . DB_PREFIX . "sku_value where id={$val}";
            $res = $this->db->query($sql);
            $row = $this->db->fetch_array($res);
            $data[] = $row;
        }
//        d($data);
        return $data;
    }

    /**
     * 获取主订单信息
     */
    public function getOrderInfo($out_trade_no) {
        $sql = "SELECT * FROM $this->table WHERE out_trade_no='{$out_trade_no}'";
        $res = $this->db->query($sql);
        $row = $this->db->fetch_array($res);
        return $row;
    }
    /**
     * 获取子订单信息
     */
    public function getOrderList($order_id) {
        $sql = "SELECT * FROM " . $this->table . "_list WHERE order_id={$order_id}";
        $res = $this->db->query($sql);
        $data = [];
        while ($row = $this->db->fetch_array($res)) {
            $data[] = $row;
        }
        return $data;
    }

    /**
     * 修改主订单
     */
    public function updateOrderInfo($out_trade_no, $data) {
        $Item = [];
        foreach ($data as $key => $var) {
            $Item[] = "$key='$var'";
        }
        $upStr = implode(',', $Item);
        $this->db->query("UPDATE $this->table SET $upStr WHERE out_trade_no = '{$out_trade_no}'");
    }





















    public function getCount($uid = UID) {
        $sql = sprintf("SELECT count(*) as num FROM $this->table WHERE author=%d AND type='%s'", $uid, 'blog');
        $res = $this->db->once_fetch_array($sql);
        return $res['num'];
    }



    public function getPostCountByUid($uid, $time = 0) {
        $date = '';
        if ($time) {
            $date = "and date > $time";
        }

        $data = $this->db->once_fetch_array("SELECT COUNT(*) AS total FROM $this->table WHERE type='blog' and author=$uid $date");
        return $data['total'];
    }

    public function getOneProductForAdmin($blogId) {
        $author = User::haveEditPermission() ? '' : 'AND author=' . UID;
        $sql = "SELECT * FROM $this->table WHERE id=$blogId $author";
        $res = $this->db->query($sql);
        if ($this->db->affected_rows() < 1) {
            emMsg('权限不足！', './');
        }
        $row = $this->db->fetch_array($res);
        if ($row) {
            $row['title'] = htmlspecialchars($row['title']);
            $row['content'] = htmlspecialchars($row['content']);
            $row['password'] = htmlspecialchars($row['password']);
            $row['template'] = !empty($row['template']) ? htmlspecialchars(trim($row['template'])) : 'page';
            return $row;
        }
        return false;
    }



    public function getDetail($blogId) {
        if (empty($blogId)) {
            return false;
        }
        $sql = "SELECT t1.*, t2.sid, t2.sortname, t2.alias as sort_alias FROM $this->table t1 LEFT JOIN $this->table_sort t2 ON t1.sortid=t2.sid WHERE t1.id=$blogId";
        $res = $this->db->query($sql);
        $row = $this->db->fetch_array($res);
        if ($row) {
            return $row;
        }
        return false;
    }

    public function getDetails($blogIds) {
        if (empty($blogIds) || !is_array($blogIds)) {
            return false;
        }
        $blogIdsString = implode(',', $blogIds);
        $sql = "SELECT t1.*, t2.sid, t2.sortname, t2.alias as sort_alias FROM $this->table t1 LEFT JOIN $this->table_sort t2 ON t1.sortid=t2.sid WHERE t1.id IN ($blogIdsString)";
        $res = $this->db->query($sql);
        $rows = array();
        while ($row = $this->db->fetch_array($res)) {
            $rows[] = $row;
        }
        return $rows;
    }

    /**
     * get single article
     * @param $blogId
     * @param bool $ignoreHide 忽略隐藏状态
     * @param bool $ignoreChecked 忽略审核状态
     * @return array|false
     */
    public function getOneProductForHome($blogId, $ignoreHide = false, $ignoreChecked = false) {
        $hide = $ignoreHide ? "" : "AND hide='n'";
        $checked = $ignoreChecked ? "" : "AND checked='y'";

        $sql = "SELECT * FROM $this->table WHERE id=$blogId $hide $checked";
        $res = $this->db->query($sql);
        $row = $this->db->fetch_array($res);

        if (!$row) {
            return false;
        }

        $sql = "SELECT * FROM " . DB_PREFIX . "product_specification WHERE goods_id=$blogId";
        $res = $this->db->query($sql);
        $product_specification = [];
        while ($product_specification_row = $this->db->fetch_array($res)) {
            $product_specification[] = $product_specification_row;
        }

        $specification_value_ids = explode('-', $product_specification[0]['specification']);
        $sql = "SELECT * FROM " . DB_PREFIX . "specification_value WHERE id IN (" . implode(',', $specification_value_ids) . ");";
        $res = $this->db->query($sql);
        $specification_value = [];
        while ($specification_row = $this->db->fetch_array($res)) {
            $specification_value[] = $specification_row;
        }
        $specification_ids = array_column($specification_value, 'specification_id');
        $sql = "SELECT * FROM " . DB_PREFIX . "specification WHERE id IN (" . implode(',', $specification_ids) . ");";
        $res = $this->db->query($sql);
        $specification = [];
        while ($specification_row = $this->db->fetch_array($res)) {
            $specification[] = $specification_row;
        }
        $specification_attr = [];
//        d($product_specification);
        foreach($specification as $key => $val){

            $specification[$key]['attr'] = [];
            foreach($product_specification as $k => $v){

                $product_specification[$k]['stock'] = (int)$v['stock'];

                $temp = explode('-', $v['specification']);
                if(!keyValueExistsInArray($specification[$key]['attr'], 'id', $temp[$key])){
                    $sql = "SELECT * FROM " . DB_PREFIX . "specification_value WHERE id={$temp[$key]}";
                    $res = $this->db->query($sql);
                    $value_temp = $this->db->fetch_array($res);
                    $specification[$key]['attr'][] = [
                        'id' => $temp[$key],
                        'name' => $value_temp['name']
                    ];
                }
            }
            $specification_attr[] = array_column($specification[$key]['attr'], 'id');
        }
        $product_specification = array_column($product_specification, null, 'specification');
        foreach($product_specification as $key => $val){
            if($val['stock'] <= 0){
                unset($product_specification[$key]);
            }
        }

//        d($specification_attr);
//        d($product_specification);
//        d($specification);





        return [
            'log_title'    => htmlspecialchars($row['title']),
            'timestamp'    => $row['date'],
            'date'         => $row['date'],
            'logid'        => (int)$row['id'],
            'sortid'       => (int)$row['sortid'],
            'type'         => $row['type'],
            'author'       => $row['author'],
            'log_cover'    => $row['cover'] ? getFileUrl($row['cover']) : '',
            'log_content'  => $this->Parsedown->text($row['content']),
            'views'        => (int)$row['views'],
            'comnum'       => (int)$row['comnum'],
            'top'          => $row['top'],
            'sortop'       => $row['sortop'],
            'hide'         => $row['hide'],
            'checked'      => $row['checked'],
            'attnum'       => (int)$row['attnum'],
            'allow_remark' => Option::get('iscomment') == 'y' ? $row['allow_remark'] : 'n',
            'password'     => $row['password'],
            'template'     => $row['template'],
            'link'         => $row['link'],
            'tags'         => $row['tags'],
            'specification' => $specification,
            'specification_attr' => $specification_attr,
            'specification_attr_json' => json_encode($specification_attr),
            'product_specification' => $product_specification,
            'product_specification_json' => json_encode($product_specification)
        ];
    }

    public function getProductForAdmin($condition = '', $hide_state = '', $page = 1, $type = 'product') {
        $perpage_num = Option::get('admin_article_perpage_num');
        $start_limit = !empty($page) ? ($page - 1) * $perpage_num : 0;
        $author = User::haveEditPermission() ? '' : 'and author=' . UID;
        $hide_state = $hide_state ? "and hide='$hide_state'" : '';
        $limit = "LIMIT $start_limit, " . $perpage_num;
        $sql = "SELECT * FROM $this->table WHERE type='$type' $author $hide_state $condition $limit";
        $res = $this->db->query($sql);
        $logs = [];
        while ($row = $this->db->fetch_array($res)) {
            $row['timestamp'] = $row['date'];
            $row['date'] = date("Y-m-d H:i", $row['date']);
            $row['title'] = !empty($row['title']) ? htmlspecialchars($row['title']) : '无标题';
            $logs[] = $row;
        }
        return $logs;
    }

    public function getProductsForHome($condition = '', $page = 1, $perPageNum = 10) {
        $start_limit = !empty($page) ? ($page - 1) * $perPageNum : 0;
        $limit = $perPageNum ? "LIMIT $start_limit, $perPageNum" : '';
        $now = time();
        $sql = "SELECT * FROM $this->table WHERE type='product' and hide='n' and checked='y' and date<= $now $condition $limit";
        $res = $this->db->query($sql);
        $logs = [];
        while ($row = $this->db->fetch_array($res)) {
            $row['log_title'] = htmlspecialchars(trim($row['title']));
            $row['log_cover'] = $row['cover'] ? getFileUrl($row['cover']) : '';
            $row['log_url'] = Url::log($row['id']);
            $row['logid'] = $row['id'];
            $cookiePassword = isset($_COOKIE['em_logpwd_' . $row['id']]) ? addslashes(trim($_COOKIE['em_logpwd_' . $row['id']])) : '';
            if (!empty($row['password']) && $cookiePassword != $row['password']) {
                $row['excerpt'] = '<p>[该文章已加密，请点击标题输入密码访问]</p>';
            }

            $row['log_description'] = $this->Parsedown->text(empty($row['excerpt']) ? $row['content'] : $row['excerpt']);
            $row['attachment'] = '';
            $row['tag'] = '';
            $row['tbcount'] = 0;
            $logs[] = $row;
        }
        return $logs;
    }

    /**
     * get rss article list
     */
    public function getLogsForRss($perPageNum = 10) {
        if ($perPageNum <= 0) {
            return [];
        }
        $now = time();
        $date_state = "and date<=$now";
        $sql = "SELECT *, t1.password as pwd FROM $this->table t1 LEFT JOIN $this->table_user t2 ON t1.author=t2.uid WHERE t1.hide='n' and t1.checked='y' and t1.type='blog' $date_state ORDER BY t1.date DESC limit 0," . $perPageNum;
        $result = $this->db->query($sql);
        $d = [];
        while ($re = $this->db->fetch_array($result)) {
            $re['id'] = $re['id'];
            $re['title'] = htmlspecialchars($re['title']);
            $re['content'] = $this->Parsedown->text($re['content']);
            if (!empty($re['pwd'])) {
                $re['content'] = '<p>[该文章已设置加密]</p>';
            } elseif (Option::get('rss_output_fulltext') == 'n') {
                if (!empty($re['excerpt'])) {
                    $re['content'] = $re['excerpt'];
                } else {
                    $re['content'] = extractHtmlData($re['content'], 330);
                }
                $re['content'] .= ' <a href="' . Url::log($re['id']) . '">阅读全文&gt;&gt;</a>';
            }
            $d[] = $re;
        }
        return $d;
    }

    /**
     * 获取文章所在页码
     * @param $date
     * @param $pageSize
     * @param $type
     * @return false|float
     */
    public function getPageOffset($date, $pageSize = 20, $type = 'blog') {
        $data = $this->db->once_fetch_array("SELECT COUNT(*) AS total FROM $this->table WHERE type='$type' AND hide='n' AND (date >= $date OR top = 'y' OR sortop = 'y')");
        $count = $data['total'];
        return ceil($count / $pageSize);
    }

    public function getAllPageList() {
        $sql = "SELECT * FROM $this->table WHERE type='page'";
        $res = $this->db->query($sql);
        $pages = [];
        while ($row = $this->db->fetch_array($res)) {
            $row['date'] = date("Y-m-d H:i", $row['date']);
            $row['title'] = !empty($row['title']) ? htmlspecialchars($row['title']) : '无标题';
            $pages[] = $row;
        }
        return $pages;
    }

    /**
     * 删除商品的规格数据
     */
    public function deleteProductSpecification($goods_id){
        $this->db->query("DELETE FROM " . DB_PREFIX . "product_specification where goods_id=$goods_id");
    }

    /**
     * 写入商品的规格数据
     */
    public function insertProductSpecification($goods_id, $sku){
        $sql = "insert into ". DB_PREFIX . "product_specification (goods_id, specification, price, market_price, cost_price, stock) values ";
        foreach($sku as $val){
            $sql .= "({$val['goods_id']}, '{$val['specification']}', {$val['price']}, {$val['market_price']}, {$val['cost_price']}, {$val['stock']}),";
        }
        $sql = rtrim($sql, ',');
        $this->db->query($sql);
    }

    public function deleteProduct($goods_id) {
        $this->checkEditable($goods_id);
        $detail = $this->getDetail($goods_id);
        $author = User::haveEditPermission() ? '' : 'and author=' . UID;
        var_dump($author);
        $this->db->query("DELETE FROM $this->table where id=$goods_id $author");
        if ($this->db->affected_rows() < 1) {
            emMsg('权限不足！', './');
        }
        // comment
        $this->db->query("DELETE FROM " . DB_PREFIX . "comment where gid=$goods_id");
        // tag
        if (!empty($detail['tags'])) {
            $TagModel = new Tag_Model();
            $tags = explode(',', $detail['tags']);
            foreach ($tags as $tag) {
                $TagModel->removeBlogIdFromTag($tag, $goods_id);
            }
        }
    }

    public function hideSwitch($blogId, $state) {
        $author = User::haveEditPermission() ? '' : 'and author=' . UID;
        $this->db->query("UPDATE $this->table SET hide='$state' WHERE id=$blogId $author");
        $this->db->query("UPDATE " . DB_PREFIX . "comment SET hide='$state' WHERE gd=$blogId");
        $Comment_Model = new Comment_Model();
        $Comment_Model->updateCommentNum($blogId);
    }

    public function checkSwitch($blogId, $state) {
        $this->db->query("UPDATE $this->table SET checked='$state' WHERE id=$blogId");
        $state = $state == 'y' ? 'n' : 'y';
        $this->db->query("UPDATE " . DB_PREFIX . "comment SET hide='$state' WHERE id=$blogId");
        $Comment_Model = new Comment_Model();
        $Comment_Model->updateCommentNum($blogId);
    }

    public function unCheck($blogId, $feedback) {
        $this->db->query("UPDATE $this->table SET checked='n', feedback='$feedback' WHERE id=$blogId");
        $this->db->query("UPDATE " . DB_PREFIX . "comment SET hide='y' WHERE id=$blogId");
        $Comment_Model = new Comment_Model();
        $Comment_Model->updateCommentNum($blogId);
    }

    public function updateViewCount($blogId) {
        $this->db->query("UPDATE $this->table SET views=views+1 WHERE id=$blogId");
    }

    public function isRepeatPost($title, $time) {
        $sql = "SELECT gid FROM $this->table WHERE title='$title' and date='$time' LIMIT 1";
        $res = $this->db->query($sql);
        $row = $this->db->fetch_array($res);
        return isset($row['gid']) ? (int)$row['gid'] : false;
    }

    public function neighborLog($date) {
        $now = time();
        $date_state = "and date<=$now";
        $neighborlog = [];
        $neighborlog['nextLog'] = $this->db->once_fetch_array("SELECT title,id FROM $this->table WHERE date < $date and hide = 'n' and checked='y' and type='blog' $date_state ORDER BY date DESC LIMIT 1");
        $neighborlog['prevLog'] = $this->db->once_fetch_array("SELECT title,id FROM $this->table WHERE date > $date and hide = 'n' and checked='y' and type='blog' $date_state ORDER BY date LIMIT 1");
        if ($neighborlog['nextLog']) {
            $neighborlog['nextLog']['title'] = htmlspecialchars($neighborlog['nextLog']['title']);
        }
        if ($neighborlog['prevLog']) {
            $neighborlog['prevLog']['title'] = htmlspecialchars($neighborlog['prevLog']['title']);
        }
        return $neighborlog;
    }

    public function getRandLog($num) {
        global $CACHE;
        $now = time();
        $date_state = "and date<=$now";
        $sta_cache = $CACHE->readCache('sta');
        $lognum = $sta_cache['lognum'];
        $start = $lognum > $num ? mt_rand(0, $lognum - $num) : 0;
        $sql = "SELECT gid,title FROM $this->table WHERE hide='n' and checked='y' and type='blog' $date_state LIMIT $start, $num";
        $res = $this->db->query($sql);
        $logs = [];
        while ($row = $this->db->fetch_array($res)) {
            $row['gid'] = (int)$row['gid'];
            $row['title'] = htmlspecialchars($row['title']);
            $logs[] = $row;
        }
        return $logs;
    }

    public function getHotLog($num) {
        $now = time();
        $date_state = "and date<=$now";
        $sql = "SELECT * FROM $this->table WHERE hide='n' and checked='y' and type='blog' $date_state ORDER BY views DESC, comnum DESC LIMIT 0, $num";
        $res = $this->db->query($sql);
        $logs = [];
        while ($row = $this->db->fetch_array($res)) {
            $row['gid'] = (int)$row['gid'];
            $row['title'] = htmlspecialchars($row['title']);
            $row['cover'] = $row['cover'] ? getFileUrl($row['cover']) : '';
            $row['log_url'] = Url::log($row['gid']);
            $logs[] = $row;
        }
        return $logs;
    }

    // 检查文章别名，别名重复则重命名为 xxx-1 格式
    public function checkAlias($alias, $logalias_cache, $logid) {
        if (!preg_match('/^[a-zA-Z0-9_\-]+$/', $alias)) {
            return '';
        }
        static $i = 2;
        $key = array_search($alias, $logalias_cache);
        if (false !== $key && $key != $logid) {
            if ($i == 2) {
                $alias .= '-' . $i;
            } else {
                $alias = preg_replace("|(.*)-([\d]+)|", "$1-{$i}", $alias);
            }
            $i++;
            return $this->checkAlias($alias, $logalias_cache, $logid);
        }
        return $alias;
    }

    public function authPassword($postPwd, $cookiePwd, $logPwd, $logid) {
        $url = EM_URL;
        $pwd = $cookiePwd ?: $postPwd;
        if ($pwd !== addslashes($logPwd)) {
            if (view::isTplExist('pw')) {
                include view::getView('pw');
            } else {
                echo <<<EOT
<!doctype html>
<html lang="zh-cn">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name=renderer  content=webkit>
<title>请输入文章访问密码</title>
<link rel="stylesheet" type="text/css" href="{$url}admin/views/css/bootstrap.min.css">
</head>
<body class="text-center">
    <form action="" method="post" class="form-signin" style="width: 100%;max-width: 330px;padding: 15px;margin: 0 auto;">
      <input type="password" id="logpwd" name="logpwd" class="form-control" placeholder="请输入文章的访问密码" required autofocus>
      <button class="btn btn-lg btn-primary btn-block mt-2" type="submit">提交</button>
      <p class="mt-5 mb-3 text-muted"><a href="$url">&larr;返回首页</a></p>
    </form>
</body>
</html>
EOT;
            }
            if ($cookiePwd) {
                setcookie('em_logpwd_' . $logid, ' ', time() - 31536000);
            }
            exit;
        }

        setcookie('em_logpwd_' . $logid, $logPwd);
    }

    public function checkEditable($gid) {
        if (User::haveEditPermission()) {
            return;
        }
        $r = $this->getOneLogForAdmin($gid);
        if (!$r || !isset($r['checked'])) {
            return;
        }
        if ($r['checked'] === 'y' && Option::get('article_uneditable') === 'y') {
            emMsg('审核通过的文章不可编辑和删除');
        }
    }
}
