<?php if (!defined('BASEPATH')) {
    exit('No direct script access allowed');
}


class Post_model extends MY_Model
{

    public function __construct()
    {
        parent::__construct();
    }

    public function getPostQuery()
    {
        get_instance()->load->library('session');
        get_instance()->db->from('cm_post p')
            ->join('cm_post_category pc', 'p.postID=pc.postID', 'left')
            ->join('cm_category c', 'pc.categoryID=c.categoryID', 'left')
            ->join('cm_post_page pp', 'p.postID=pp.postID', 'left');
        if (!isAdminSite() && !get_instance()->session->userdata('userName')) {
            get_instance()->db->where('p.published', 1);
        }
        return get_instance()->db;
    }

    public function getPostsByCategoryId($categories, $limit, $offset = 0)
    {
        $categories = is_array($categories) ? $categories : [$categories];
        return $this->getPostQuery()
            ->where_in('c.categoryID', $categories)
            ->limit($limit)->order_by('datePosted', 'desc')
            ->offset($offset)
            ->select('*, p.postID postSeq');
    }

    public function getPagePostsByCategoryId($categories, $limit, $offset = 0)
    {
        $categories = is_array($categories) ? $categories : [$categories];
        return $this->getPostQuery()
            ->join('cm_page_content co', 'pp.pageID=co.pageID', 'left')
            ->where_in('c.categoryID', $categories)
            ->limit($limit)->order_by('datePosted', 'desc')
            ->offset($offset);
    }

    public function getPagePostsByPageId($PageId, $limit = 0, $offset = 0)
    {
        $PageId = is_array($PageId) ? $PageId : [$PageId];
        return $this->getPostQuery()
            ->join('cm_page_content co', 'pp.pageID=co.pageID', 'left')
            ->join('cm_page_attributes pa', 'pp.pageID=pa.pageID', 'left')
            ->where_in('pp.pageID', $PageId)
            ->limit($limit)->order_by('datePosted', 'desc')
            ->offset($offset)
            ->select('*, p.postID postSeq')
            ->group_by('p.postID');
    }

    public function getCountPostsByCategoryId($categories)
    {
        $categories = is_array($categories) ? $categories : [$categories];
        return $this->getPostQuery()
            ->where_in('c.categoryID', $categories)
            ->count_all_results();
    }

    public function getCountPostsByPageId($pageId)
    {
        $pageId = is_array($pageId) ? $pageId : [$pageId];
        return $this->getPostQuery()
            ->where_in('pp.pageID', $pageId)
            ->count_all_results();
    }

    public function getPostsByPageId($pageId, $limit)
    {
        $pageId = is_array($pageId) ? $pageId : [$pageId];
        return $this->getPostQuery()
            ->where_in('pp.pageID', $pageId)
            ->limit($limit)->order_by('datePosted', 'desc')
            ->select('*, p.postID postSeq')
            ->group_by('p.postID');
    }

    public function getPostsRatingByPageId($pageId, $limit)
    {
        $pageId = is_array($pageId) ? $pageId : [$pageId];
        return $this->getPostQuery()
            ->join('cm_post_ranking pr', "p.postID=pr.postID", 'left')
            ->where_in('pp.pageID', $pageId)
            ->limit($limit)
            ->group_by('p.postID')
            ->select('*, p.postID postSeq');
    }

    public function getPostsByPageIdAndCategoryId($pageId, $categoryId, $limit)
    {
        $pageId = is_array($pageId) ? $pageId : [$pageId];
        $categoryId = is_array($categoryId) ? $categoryId : [$categoryId];
        return $this->getPostQuery()
            ->where_in('c.categoryID', $categoryId)
            ->where_in('pp.pageID', $pageId)
            ->limit($limit)->order_by('datePosted', 'desc');
    }

    public function getCountPostsByPageIdAndCategoryId($pageId, $categoryId)
    {
        $pageId = is_array($pageId) ? $pageId : [$pageId];
        $categoryId = is_array($categoryId) ? $categoryId : [$categoryId];
        return $this->getPostQuery()
            ->where_in('c.categoryID', $categoryId)
            ->where_in('pp.pageID', $pageId)
            ->order_by('datePosted', 'desc')->count_all_results();
    }

    public function getPostsRankingByRankTypeAndCategoryId($rankType, $categoryId, $limit)
    {
        $categoryId = is_array($categoryId) ? $categoryId : [$categoryId];
        return $this->getPostQuery()
            ->join('cm_post_ranking pr', "p.postID=pr.postID and pr.title='$rankType'", 'left')
            ->where_in('c.categoryID', $categoryId)
            ->group_by('p.postID')
            ->limit($limit)->order_by('datePosted', 'desc')
            ->select('*, p.postID postSeq');
    }

    public function getPost($postURL)
    {
        return isAdminSite() ? (function () use ($postURL) {
            return $this->getPostQuery()
                ->join('cm_post_thumb t', 'p.postID=t.postID', 'left')
                ->join('cm_post_schedule s', 'p.postID=s.postID', 'left')
                ->where('p.postID', $postURL)
                ->select('p.*, c.*, t.thumb postThumb, s.run_at dateReserved')->group_by('p.postID');
        })() : $this->getPostQuery()->where('p.postURL', $postURL)->select('*, p.postID postSeq')->get()->row();
    }

    public function getPosts($limit, $offset)
    {
        if (isAdminSite()) {
            if ($term = getSearchTerm()) {
                $this->db->like("p.postTitle", $term)->or_like("p.postExcerpt", $term)
                    ->or_like("c.categoryTitle", $term)->or_where('p.postID', $term)
                    ->or_like('pcn.pageTitle', $term);
            }
            return $this->getPostQuery()
                ->join('cm_user u', 'p.userID = u.userID', 'left')
                ->join('cm_page_content pcn', 'pp.pageID=pcn.pageID', 'left')
                ->group_by('p.postID')->order_by('dateUpdated', 'desc')
                ->limit($limit)->offset($offset);
        }
    }

    public function getPostsRankingByPostId($postId)
    {
        return $this->db->where_in('postID', $postId)->from('cm_post_ranking');
    }

    public function getPostsScheduled()
    {
        return get_instance()->db->where('done', 'N')->get('cm_post_schedule')->result();
    }

    public function publishPosts($postIds)
    {
        get_instance()->db->where_in('postID', $postIds)->update('cm_post', ['published' => 1]);
        get_instance()->db->where_in('postID', $postIds)->update('cm_post_schedule', ['done' => 'Y']);
        return get_instance()->db->affected_rows();
    }

    public function save()
    {
        $categoryID = 0;
        $data = array(
            'postTitle' => $this->input->post('postTitle'),
            'postSubTitle' => $this->input->post('postSubTitle'),
            'categoryID' => $categoryID,
            // 'postURL' => $this->input->post('postURL'),
            // 'postContent' => $this->input->post('content'),
            'postContentHTML' => $this->input->post('content'),
            'postExcerpt' => $this->input->post('postExcerpt'),
            'published' => $this->input->post('published'),
            'datePosted' => date('Y-m-d H:i:s'),
            'dateUpdated' => date('Y-m-d H:i:s'),
            'unixStamp' => $this->input->post('unixStamp'),
        );
        if ($this->input->post('postImage') != "") {
            $data['postImage'] = $this->input->post('postImage');
        }
        $this->db->insert('cm_post', $data);
        $insertID = $this->db->insert_id();

        if ($this->input->post('postTag')) {
            $this->db->where('postID', $insertID)->delete('cm_post_tag');
            $this->db->insert('cm_post_tag', ['postID' => $insertID, 'tag' => $this->input->post('postTag')]);
        }

        $this->postThumbnail($insertID, $this->input->post('postThumb'));
        $this->addPostCategory($insertID, $this->input->post('categories') ? explode(',', $this->input->post('categories')) : []);
        $this->addPostPage($insertID, $this->input->post('pages') ? explode(',', $this->input->post('pages')) : []);
        $this->db->where('postID', $insertID)->update('cm_post', array('postURL' => $insertID));
    }

    public function update($id)
    {
        $categoryID = 0;
        $this->addPostCategory($id, $this->input->post('categories') ? explode(',', $this->input->post('categories')) : []);
        $this->addPostPage($id, $this->input->post('pages') ? explode(',', $this->input->post('pages')) : []);

        if ($this->input->post('video')) {
            $this->db->where('postID', $id)->update('cm_post_video', ['videoURL' => '']);
        }

        if ($this->input->post('postTag')) {
            $this->db->where('postID', $id)->delete('cm_post_tag');
            $this->db->insert('cm_post_tag', ['postID' => $id, 'tag' => $this->input->post('postTag')]);
        }

        $data = array(
            'postTitle' => $this->input->post('postTitle'),
            'postSubTitle' => $this->input->post('postSubTitle'),
            'categoryID' => $categoryID,
            // 'postURL' => $this->input->post('postURL'),
            'postContentHTML' => $this->input->post('content'),
            'postExcerpt' => $this->input->post('postExcerpt'),
            'published' => $this->input->post('published'),
            'dateUpdated' => date('Y-m-d H:i:s'),
            'unixStamp' => $this->input->post('unixStamp'),
            'userID' => $this->input->post('userID')
        );
        if ($this->input->post('postImage')) {
            $data['postImage'] = '/images/' . date('Y/m/d/') . $this->input->post('postImage');
        }
        $this->postThumbnail($id, $this->input->post('postThumb'));
        $this->db->where("postID", $id);
        $this->db->update('cm_post', $data);
    }

    private function postThumbnail($postId, $thumb)
    {
        if ($thumb) {
            $thumb = '/thumbs/' . date('Y/m/d/') . $thumb;
            $this->db->where('postID', $postId)->delete('cm_post_thumb');
            $this->db->insert('cm_post_thumb', ['postID' => $postId, 'thumb' => $thumb]);
            return $this->db->insert_id();
        }
    }

    public function addPostCategory($postID, $categories)
    {
        $tmp = [];
        $this->db->where('postID', $postID)->delete('cm_post_category');
        if (count($categories)) {
            return $this->db->insert_batch('cm_post_category', array_filter(array_map(function ($category) use ($postID) {
                return ['postID' => $postID, 'categoryID' => $category];
            }, $categories), function ($c) use (&$tmp) {
                $isDup = $c['categoryID'] ? false : true;
                if (!$isDup) {
                    foreach ($tmp as $t) {
                        if ($t['categoryID'] == $c['categoryID']) {
                            $isDup = true;
                            break;
                        }
                    }
                }
                array_push($tmp, $c);
                if (!$isDup) {
                    return $c;
                }
            }));
        }
    }

    public function addPostPage($postID, $pages)
    {
        $tmp = [];
        $this->db->where('postID', $postID)->delete('cm_post_page');
        if (count($pages)) {
            return $this->db->insert_batch('cm_post_page', array_filter(array_map(function ($page) use ($postID) {
                return ['postID' => $postID, 'pageID' => $page];
            }, $pages), function ($c) use (&$tmp) {
                $isDup = $c['pageID'] ? false : true;
                if (!$isDup) {
                    foreach ($tmp as $t) {
                        if ($t['pageID'] == $c['pageID']) {
                            $isDup = true;
                            break;
                        }
                    }
                }
                array_push($tmp, $c);
                if (!$isDup) {
                    return $c;
                }
            }));
        }
    }

    public function getPostVideo($postId)
    {
        return $this->db->where('postID', $postId)->get('cm_post_video')->row();
    }

    public function getPostTag($postId)
    {
        $query = $this->db->where('postID', $postId)->get('cm_post_tag');
        return $query->num_rows() ? array_map(function ($row) {
            $row['tag'] = explode(strpos($row['tag'], ',') ? ',':' ', $row['tag']);
            return $row;
        }, $query->result_array())[0] : ['tag' => []];
    }
}
