<?php
/**
 * @package merchant
 * @Author: Qinii
 * @Date: 2020/5/8
 */

namespace app\common\repositories\movie;

use app\common\model\movie\cinema\CinemaSched;
use app\common\repositories\BaseRepository;
use crmeb\services\ApiResponseService;
use think\facade\Db;

/**
 * Class CinemaSchedRepository
 * @package app\common\repositories\movie
 * @author xaboy
 * @mixin CinemaSched
 */
class CinemaSchedRepository extends BaseRepository
{
    protected $dao;

    /**
     * ProductRepository constructor.
     * @param CinemaSched $dao
     */
    public function __construct(CinemaSched $dao)
    {
        $this->dao = $dao;
    }

    /**
     * @param $film_sign
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getFilmSchedDate($film_sign)
    {
        $field = 'show_date';
        $where = ['film_sign' => $film_sign, 'date' => strtotime(date('Y-m-d'))];

        $show_date = $this->dao->search(null, $where)->field([$field])->order('show_date asc')->group('show_date')->select()->toArray();
        foreach ($show_date as $key => $value) {
            $show_date[$key]['date'] = date('m-d', $value['show_date']);
        }

        return $show_date;
    }

    /**
     * @param $page
     * @param $limit
     * @param $longitude
     * @param $latitude
     * @param $show_date
     * @param $with
     * @param $order
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getFilmSched($page, $limit, $film_sign, $longitude, $latitude, $city_sign)
    {
        /** @var MovieRepository $movieRepository */
        $movieRepository = app()->make(MovieRepository::class);
        $result = $movieRepository->getFilmSched($page, $limit, $film_sign, $longitude, $latitude, $city_sign);
        $cinema_sched = (isset($result['code']) && ($result['code'] == ApiResponseService::DEFAULT_SUCCESS_CODE))
            ? $result['data']['list'] : [];
        $count = (isset($result['code']) && ($result['code'] == ApiResponseService::DEFAULT_SUCCESS_CODE))
            ? $result['data']['paging']['total'] : 0;
        $pages = (isset($result['code']) && ($result['code'] == ApiResponseService::DEFAULT_SUCCESS_CODE))
            ? $result['data']['paging']['pages'] : 0;

        return compact('cinema_sched', 'count', 'pages');
    }

    /**
     * @param $page
     * @param $limit
     * @param $longitude
     * @param $latitude
     * @param $show_date
     * @param $with
     * @param $order
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getFilmSchedBak($page, $limit, $film_sign, $longitude, $latitude, $show_date, $show_time, $with = [], $order = 1)
    {
        $field = 'sched_sign,cinema_sign,cinema_name,address,show_date,price,longitude,latitude';
        $where = ['film_sign' => $film_sign, 'show_date' => $show_date];
        if ($show_date == strtotime(date('Y-m-d'))) $where['show_time'] = $show_time;

        $movie_commission_rate_config = Db::name('system_config_value')->where('config_key', 'movie_commission_rate_config')->find();
        $movie_commission_rate_config = !empty($movie_commission_rate_config) ? json_decode($movie_commission_rate_config['value'], true) : [];

        $cinema_sched = $this->dao->search(null, $where)->when($with, function ($query) use ($with) {
            $query->with($with);
        })->when($latitude && $longitude, function ($query) use ($field, $longitude, $latitude) {
            $query->field([$field, $this->distance($latitude, $longitude)]);
        })->when($page && $limit, function ($query) use ($page, $limit) {
            $query->page($page, $limit);
        })->when(!is_null($order), function ($query) use ($order) {
            if ($order == 1) {//距离最近
                $query->order('distance asc');
            } else {//播放日期
                $query->order('show_time asc');
            }
        })->field([$field])->group('cinema_sign')->select()->toArray();
        foreach ($cinema_sched as $key => $value) {
            $cinema_sched[$key]['distance'] = isset($value['distance']) ? round($value['distance'] / 1000, 2) : 0.00;
            $cinema_sched[$key]['show_date'] = date('m-d', $value['show_date']);

            $pcYanglaojinGongxian = MovieRepository::getPvYanglaojinScore($value['price'], $movie_commission_rate_config);
            $cinema_sched[$key]['price'] = $pcYanglaojinGongxian['cost_price'];
        }

        $count = $this->dao->search(null, $where)->when($with, function ($query) use ($with) {
            $query->with($with);
        })->when($latitude && $longitude, function ($query) use ($field, $longitude, $latitude) {
            $query->field([$field, $this->distance($latitude, $longitude)]);
        })->group('cinema_sign')->count();

        return compact('cinema_sched', 'count');
    }

    /**
     * 获取影片场次列表
     *
     * @param $cinema_sign
     * @param $film_sign
     * @param $show_date
     * @param $show_time
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getCinemaFilmSchedNew($film_sign, $cinema_sign)
    {
        /** @var FilmRepository $filmRepository */
        $filmRepository = app()->make(FilmRepository::class);
        $filminfo = $filmRepository->getFilmInfo($film_sign);
        if (empty($filminfo)) throw new \Exception('影片不存在');

        /** @var CinemaRepository $cinemaRepository */
        $cinemaRepository = app()->make(CinemaRepository::class);
        $cinemainfo = $cinemaRepository->getCinemaInfo($cinema_sign);

        // 获取排片场次
        /** @var MovieRepository $movieRepository */
        $movieRepository = app()->make(MovieRepository::class);
        $cinema_sched = $movieRepository->getCinemaSched($film_sign, $cinema_sign);

        // 排片日期
        $show_date = [];
        $show_date_tmp = array_keys($cinema_sched);
        foreach ($show_date_tmp as $sdKey => $sdValue) {
            $show_date[$sdKey] = [
                'date_timestamp' => strtotime(date('Y') . '-' . $sdValue),
                'date' => $sdValue,
            ];
        }
        // 场次列表
        foreach ($cinema_sched as $date => &$cinema_schedValue) {
            foreach ($cinema_schedValue as $key => $value) {
                $cinema_schedValue[$key]['cinema_sign'] = $cinemainfo->cinema_sign;
                $cinema_schedValue[$key]['cinema_name'] = $cinemainfo->cinema_name;
                $cinema_schedValue[$key]['end_time'] = date('H:i', (strtotime($value['show_time']) + $filminfo['duration'] * 60));
                $cinema_schedValue[$key]['film'] = [
                    'film_sign' => $filminfo->film_sign,
                    'publish_date' => date('Y-m-d', $filminfo->publish_date),
                    'language' => $filminfo->language,
                    'type' => $filminfo->type,
                    'duration' => $filminfo->duration,
                    'version' => $filminfo->version
                ];
                unset($cinema_schedValue[$key]['channel_price']);
                unset($cinema_schedValue[$key]['cost_price']);
            }
        }

        return compact('show_date', 'cinema_sched');
    }

    /**
     * @param $page
     * @param $limit
     * @param $cinema_sign
     * @param $film_sign
     * @param $show_date
     * @param $show_time
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getCinemaFilmSched($page, $limit, $cinema_sign, $film_sign, $show_date, $show_time)
    {
        $field = 'relation_id,sched_sign,film_sign,film_name,show_date,show_time,cinema_sign,cinema_name,hall_sign,hall_name,price';
        $where = ['cinema_sign' => $cinema_sign, 'film_sign' => $film_sign, 'show_date' => $show_date];
        if ($show_date == strtotime(date('Y-m-d'))) $where['show_time'] = $show_time;

        $cinema_sched = $this->dao->search(null, $where)
            ->when($page && $limit, function ($query) use ($page, $limit) {
                $query->page($page, $limit);
            })->order('show_time asc')->field([$field])->select()->toArray();

        $filmList = [];
        $film_sign_list = array_column($cinema_sched, 'film_sign');
        if (!empty($film_sign_list)) {
            $tmpFilmList = Db::name('movie_film')->whereIn('film_sign', $film_sign_list)->field('film_sign,publish_date,language,type,duration,version')->select()->toArray();
            foreach ($tmpFilmList as $fKey => $fValue) {
                $fValue['publish_date'] = date('Y-m-d', $fValue['publish_date']);
                $filmList[$fValue['film_sign']] = $fValue;
            }
        }
        $movie_commission_rate_config = Db::name('system_config_value')->where('config_key', 'movie_commission_rate_config')->find();
        $movie_commission_rate_config = !empty($movie_commission_rate_config) ? json_decode($movie_commission_rate_config['value'], true) : [];

        foreach ($cinema_sched as $key => $value) {
            $pcYanglaojinGongxian = MovieRepository::getPvYanglaojinScore($value['price'], $movie_commission_rate_config);

            $cinema_sched[$key]['price'] = $pcYanglaojinGongxian['cost_price'];
            $cinema_sched[$key]['yanglaojin'] = $pcYanglaojinGongxian['yanglaojin'];
            $cinema_sched[$key]['pv'] = $pcYanglaojinGongxian['pv'];
            $cinema_sched[$key]['score'] = $pcYanglaojinGongxian['score'];
            $cinema_sched[$key]['gongxian'] = $pcYanglaojinGongxian['gongxian'];

            $film = $filmList[$value['film_sign']] ?? [];
            $cinema_sched[$key]['end_time'] = !empty($film) ? date('H:i', (strtotime($value['show_time']) + $film['duration'] * 60)) : '';
            $cinema_sched[$key]['film'] = $film;
        }

        $count = $this->dao->search(null, $where)->count();

        return compact('cinema_sched', 'count');
    }

    /**
     * 经纬度排序计算
     * @param string $latitude
     * @param string $longitude
     * @return string
     */
    private function distance(string $latitude, string $longitude)
    {
        return "(round(6378137 * 2 * asin(sqrt(pow(sin(((latitude * pi()) / 180 - ({$latitude} * pi()) / 180) / 2), 2) 
        + cos(({$latitude} * pi()) / 180) * cos((latitude * pi()) / 180) * pow(sin(((longitude * pi()) / 180 - ({$longitude} * pi()) / 180) / 2), 2))))) AS distance";
    }

    /**
     * 获取影片场次详情
     *
     * @param $relation_id
     * @param $sched_sign
     * @return CinemaSched|array|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getCinemaSchedInfo($relation_id, $sched_sign)
    {
        return $this->dao->search(null, ['relation_id' => $relation_id, 'sched_sign' => $sched_sign])->find();
    }
}
