<?php

declare(strict_types=1);

namespace app\common\model;

use app\common\model\account\Department;
use app\common\model\account\User as UserModel;
use mb\helper\Collection;
use Exception;
use think\facade\Db;
use app\control\model\User;
use think\facade\Log;

/**
 * Class News
 * @package app\common\model
 */
class News
{
    /**
     * title 新闻名称
     * founder 创建人id
     * timeCreatedMax  最大搜索时间
     * timeCreatedMin  最小搜索时间
     * @param array $filter
     * @param int $pIndex
     * @param int $pSize
     * @param int $total
     * @return array
     * @throws Exception
     */
    public static function search(array $filter, int $pIndex = 1, int $pSize = 10, &$total = 0)
    {
        $user = User::fetchCurrent();
        $where = [];
        if (!empty($filter['title'])) {
            $where[] = ['title', 'like', "%{$filter['title']}%"];
        }
        if (!empty($filter['founder'])) {
            $where[] = ['founder', '=', $filter['founder']];
        }
        if (!empty($filter['timeCreatedMax'])) {
            $where[] = ['time_created', '<=', strtotime($filter['timeCreatedMax'])];
        }
        if (!empty($filter['timeCreatedMin'])) {
            $where[] = ['time_created', '>=', strtotime($filter['timeCreatedMin'])];
        }
        if (!empty($filter['ids'])) {
            $where[] = ['id', 'in', "{$filter['ids']}"];
        }
        if ($user['role'] == 'user') {
            $ids = self::userWatch();
            $ids = implode(',', $ids);
            $where[] = ['id', 'in', "{$ids}"];
        }
        try {
            $total = Db::table('news')->where($where)->count();
            $query = Db::table('news')->where($where);
            if (!empty($pIndex)) {
                $query->page($pIndex, $pSize);
            }
            $dataSet = $query->select()->toArray();
            if (!empty($dataSet)) {
                return array_map(function ($row) {
                    $row = Collection::keyStyle($row, Collection::NAME_STYLE_JAVA);
                    if (!empty($row['watch'])) {
                        $row['watch'] = unserialize($row['watch']);
                    }
                    if (!empty($row['watch']['user'])) {
                        $row['watch']['user'] = array_map(function ($v) {
                            $user = UserModel::fetch(intval($v));
                            if (!empty($user)) {
                                $department = Department::fetch($user['department']);
                                $user = [
                                    'id' => $user['id'],
                                    'uid' => $user['uid'],
                                    'name' => $user['name'],
                                    'department' => $department['id'],
                                    'departmentTitle' => $department['title'],
                                ];
                            }
                            return $user;
                        }, $row['watch']['user']);
                    }
                    if (empty($val['watch']['user']) && empty($val['watch']['department'])) {
                        $val['watch'] = "";
                    }
                    return $row;
                }, $dataSet);
            } else {
                return [];
            }
        } catch (Exception $e) {
            Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR);
        }
        return error(-1, '查询失败');
    }

    /**
     * title 新闻标题
     * content 新闻内容
     * founder 创建人id
     * watch 可查看人员
     * @param $newsData
     * @return int|string
     */
    public static function add($newsData)
    {
        $newsData = Collection::keyStyle($newsData, Collection::NAME_STYLE_C);
        $newsData = Collection::elements(['title','content','founder','watch'], $newsData);
        $newsData['time_created'] = time();
        $newsData['view'] = 0;
        try {
            $watch = $newsData['watch'];
            $newsData['watch'] = serialize($newsData['watch']);
            $id = Db::table('news')
                ->insertGetId($newsData);
            $arr = [
                'paramId' => $id,
                'department' => $watch['department'],
                'user' => $watch['user']
            ];
            Base::watch('news', $arr);
            return $id;
        } catch (Exception $e) {
            Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR);
        }
        return 0;
    }

    /**
     * where.id
     * newData.title
     * newData.content
     * newData.founder
     * newData.watch
     * @param array $where
     * @param array $newData
     * @return bool
     */
    public static function update(array $where, array $newData)
    {
        try {
            $watch = $newData['watch'];
            $newData['watch'] = serialize($newData['watch']);
            $offect = Db::table('news')
                ->where($where)
                ->update($newData);
            if ($offect === 1) {
                $arr = [
                    'paramId' => $where['id'],
                    'department' => $watch['department'],
                    'user' => $watch['user']
                ];
                Base::watch('news', $arr);
                return true;
            }
            return false;
        } catch (Exception $e) {
            Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR);
        }
        return false;
    }

    /**
     * @param string $type
     * @param string $ids
     * @return bool
     */
    public static function delete(string $type, string $ids)
    {
        if ($type == 'single') {
            $where[] = ['id', '=', $ids];
            $watchWhere[] = ['news_id', '=', $ids];
        } else {
            $where[] = ['id', 'in', "{$ids}"];
            $watchWhere[] = ['news_id', 'in', "{$ids}"];
        }
        try {
            $offect = Db::table('news')
                ->where($where)
                ->delete();
            if ($offect) {
                Db::table('news_watch')->where($watchWhere)->delete();
                return true;
            }
            return false;
        } catch (Exception $e) {
            Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR);
        }
        return false;
    }

    /**
     * where.id 新闻id
     * @param array $where
     * @return array
     */
    public static function detail(array $where)
    {
        try {
            $detail = Db::table('news')
                ->where($where)
                ->find();
            if (!empty($detail)) {
                return Collection::keyStyle($detail, Collection::NAME_STYLE_JAVA);
            } else {
                return [];
            }
        } catch (Exception $e) {
            Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR);
        }
        return [];
    }

    /**
     * @return array
     */
    public static function founder()
    {
        try {
            $founder = Db::table('news')
                ->group('founder')
                ->field('founder')
                ->select()->toArray();
            $founder = Base::neaten($founder, 'founder');
            return $founder;
        } catch (Exception $e) {
            Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR);
        }
        return [];
    }

    /**
     * @param $ids
     * @param string $type
     * @return bool
     * @throws Exception
     */
    public static function check($ids, $type = 'single')
    {
        $user = User::fetchCurrent();
        if ($type == 'single') {
            $detail = self::detail(['id' => $ids]);
            if (($user['role'] != 'root') && ($detail['founder'] != $user['id'])) {
                return false;
            } else {
                return true;
            }
        } else {
            $filter = ['ids' => $ids];
            $news = self::search($filter, 0);
            foreach ($news as $v) {
                if (($user['role'] != 'root') && ($v['founder'] != $user['id'])) {
                    return false;
                } else {
                    return true;
                }
            }
        }
    }

    /**
     * @return array
     */
    public static function userWatch()
    {
        try {
            $user = User::fetchCurrent();
            $subjectIds = Db::table('news_watch')->where(
                "`type` = '' or (`type` = 'department' and `binding_id` = {$user['department']}) 
            or (`type` = 'user' and `binding_id` = {$user['id']})"
            )->group('news_id')->field('news_id')->select()->toArray();
            return Base::neaten($subjectIds, 'news_id');
        } catch (Exception $e) {
            Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR);
        }
        return [];
    }

}