<?php

namespace CCDN\Controllers;

use CCDN\Helpers\Api\ApiHandler;
use CCDN\Helpers\Api\Response\Field\SerialStatus;
use CCDN\Helpers\Api\Response\VideoNews;
use CCDN\Helpers\Api\ResponseFactory;
use CCDN\Helpers\Arr;
use CCDN\Helpers\CCDNUploadPoster;
use CCDN\Helpers\Controller;
use CCDN\Helpers\DB\Model;
use CCDN\Helpers\DB\SettingsSave;
use CCDN\Helpers\Entities\Post;
use CCDN\Helpers\Exception\CCDNException;
use CCDN\Helpers\Facade\Api\Response\Field\TypeField;
use CCDN\Helpers\Facade\DB\Model as ModelStatic;
use CCDN\Helpers\Facade\Http\Response;
use CCDN\Helpers\Facade\Http\Url;
use CCDN\Helpers\Http\Request;
use CCDN\Helpers\Modules\Module\PatterParser;
use CCDN\Helpers\NotSeasonsFranchiseAltUrl;
use CCDN\Helpers\NotSeasonsFranchiseMetaTitle;
use CCDN\Helpers\NotSeasonsFranchiseTitle;
use CCDN\Helpers\PostCategories;
use CCDN\Helpers\SeasonsFranchiseAltUrl;
use CCDN\Helpers\SeasonsFranchiseMetaTitle;
use CCDN\Helpers\SeasonsFranchiseTitle;
use CCDN\Helpers\CCDNFunctions;
use CCDN\Helpers\Settings;
use CCDN\Helpers\XFields;
use URLify;

class NewFranchiseController extends Controller
{
    protected $viewsFolder = 'new-franchise';
    protected $parent = '';

    public function __construct($parent = 'new-franchise')
    {
        $this->parent = $parent;
    }

    public function main()
    {
        global $cat_info;

        $api = new ApiHandler();

        $ccdnConf = Settings::all();

        $categoryBundle = $ccdnConf->getJsonDecode('category_bundle');
        $typeBundle = $ccdnConf->getJsonDecode('type_bundle');
        $countryBundle = $ccdnConf->getJsonDecode('country_bundle');
        $serialStatusBundle = $ccdnConf->getJsonDecode('serial_status_bundle');

        $countries = ResponseFactory::createCountry($api->getCountry([
            'limit' => 500
        ])->getBody());
        $genres = ResponseFactory::createGenre($api->getGenres([
            'limit' => 500
        ])->getBody());

        $customFields = XFields::load();

        $customFieldsTable = [];

        foreach ($customFields as $field) {
            $customFieldsTable[$field['key']] = $field['name'];
        }

        return Response::make($this->render('new-franchise', [
            'ccdnConf' => $ccdnConf,
            'customFields' => $customFields,
            'customFieldsTable' => $customFieldsTable,
            'categories' => CCDNFunctions::getSequenceOfCategories($cat_info),
            'categoryBundle' => $categoryBundle,
            'countryBundle' => $countryBundle,
            'typeBundle' => $typeBundle,
            'serialStatusBundle' => $serialStatusBundle,
            'franchiseTypes' => TypeField::getTypes(),
            'genres' => $genres,
            'countries' => $countries,
            'segments' => new PatterParser(),
            'serialStatus' => new SerialStatus(),

        ]));
    }

    public function saveConfig(Request $request)
    {
        $settings = $request->post();
        $categoryBundle = $request->post('category_bundle');
        $typeBundle = $request->post('type_bundle');
        $countryBundle = $request->post('country_bundle');
        $serialStatusBundle = $request->post('serial_status_bundle');


        $settings['category_bundle'] = json_encode(array_filter($categoryBundle), JSON_UNESCAPED_UNICODE);
        $settings['type_bundle'] = json_encode(array_filter($typeBundle), JSON_UNESCAPED_UNICODE);
        $settings['country_bundle'] = json_encode(array_filter($countryBundle), JSON_UNESCAPED_UNICODE);
        $settings['serial_status_bundle'] = json_encode(array_filter($serialStatusBundle), JSON_UNESCAPED_UNICODE);

        $configSave = new SettingsSave($settings);
        $configSave->newFranchise();

        Response::redirect(Url::to($this->parent));
    }

    public function getNewFranchise()
    {
        $api = new ApiHandler();

        $franchiseListAll = $api->getVideoNewsAll();
        unset($api);
        $subDaysTimestamp = strtotime('-4 day');
        $franchiseListAll = Arr::unique($franchiseListAll, 'id');
        $franchiseListAll = Arr::filter($franchiseListAll, static function ($value, $key) use ($subDaysTimestamp) {
            return strtotime($value['activate_time']) > $subDaysTimestamp;
        });

        if (empty($franchiseListAll)) {
            return Response::json([
                'data' => [],
            ]);
        }

        $kinopoiskIdField = Settings::get('kinopoisk_id_field');
        $ccdnIdField = Settings::get('ccdn_id_field');

        $whereIn = [];

        foreach ($franchiseListAll as $key => $franchise) {
            unset($franchiseListAll[$key]['episode'],
                $franchiseListAll[$key]['season'],
                $franchiseListAll[$key]['origin_name'],
                $franchiseListAll[$key]['created_time'],
                $franchiseListAll[$key]['imdb_id'],
                $franchiseListAll[$key]['world_art'],
                $franchiseListAll[$key]['world_art_id'],
                $franchiseListAll[$key]['voice_acting']
            );
            $franchise = new VideoNews($franchise);
            $franchiseListAll[$key]['activate_time'] = date('Y-m-d',
                strtotime($franchiseListAll[$key]['activate_time']));
            $franchiseListAll[$key]['type'] = $franchise->getType()->getName();
            $franchiseListAll[$key]['has_in_db'] = false;

            $whereIn['collaps_id'][] = $franchise->getId();

            if (($kp_id = $franchise->getKinopoiskId()) !== null) {
                $whereIn['kinopoisk_id'][] = $kp_id;
            }
        }

        $whereIn['collaps_id'] = implode(',', $whereIn['collaps_id']);
        $whereIn['kinopoisk_id'] = implode(',', $whereIn['kinopoisk_id']);

        $dbPrefix = ModelStatic::getPrefix();

        $query = "SELECT * FROM (SELECT id, SUBSTRING_INDEX(SUBSTRING_INDEX(xfields, '{$ccdnIdField}|', -1), '|', 1) AS collaps_id";

        if ($kinopoiskIdField) {
            $query .= ", SUBSTRING_INDEX(SUBSTRING_INDEX(xfields, '{$kinopoiskIdField}|', -1), '|', 1) AS kinopoisk_id";
        }

        $query .= " FROM `{$dbPrefix}_post`) as t WHERE t.collaps_id IN ({$whereIn['collaps_id']})";
        if ($kinopoiskIdField && $whereIn['kinopoisk_id']) {
            $query .= " OR t.kinopoisk_id IN ({$whereIn['kinopoisk_id']})";
        }
        $queryResult = ModelStatic::select($query, true);

        foreach ($franchiseListAll as $key => $franchise) {
            $item = new VideoNews($franchise);
            $collaps_id = (int)$item->getId();
            $kp_id = $item->getKinopoiskId();

            foreach ($queryResult as $postItem) {
                if ($kinopoiskIdField && $kp_id !== null && (string)$postItem['kinopoisk_id'] !== (string)$kp_id) {
                    continue;
                }

                if ((int)$postItem['collaps_id'] !== $collaps_id)
                    continue;

                $franchiseListAll[$key]['has_in_db'] = true;
                $franchiseListAll[$key]['post_url'] = Url::toAdminPanel() . "?mod=editnews&action=editnews&id={$postItem['id']}";
                break;
            }
        }

        return Response::json([
            'data' => $franchiseListAll,
        ]);
    }


    /**
     * @param Request $request
     * @return string
     * @throws CCDNException
     */
    public function createPost(Request $request)
    {
        global $member_id, $config;

        $id = $request->post('collaps_id');
        $ccdnConf = Settings::all();

        $model = new Model();
        $query = "SELECT * FROM (SELECT id,
 SUBSTRING_INDEX(SUBSTRING_INDEX(xfields, '{$ccdnConf->ccdn_id_field}|', -1), '|', 1) AS collaps_id
 FROM `{$model->getPrefix()}_post`) as t WHERE t.collaps_id = {$model->getDb()->safesql($id)}";

        if ($model->select($query)) {
            throw new CCDNException('Post is exist', 404);
        }

        $api = new ApiHandler();
        $response = $api->getFranchiseDetails([
            'id' => $id,
        ]);

        if ($response === null) {
            throw new CCDNException("Not found. Collaps id: {$id}", 404);
        }

        $season = '';
        $episode = '';

        $seasonsNumber = $response->getSeasons()->getLast()->getNumber();
        $episodesNumber = $response->getSeasons()->getLast()->getEpisodes()->getLast()->getNumber();

        if (!empty($seasonsNumber)) {
            $season = $seasonsNumber . ' ' . $ccdnConf->serial_season_field_suffix;
        }
        if (!empty($episodesNumber)) {
            $episode = $episodesNumber . ' ' . $ccdnConf->serial_episode_field_suffix;
        }


        $disabledVoices = (array)$ccdnConf->getJsonDecode('video_voices_disabled');

        $iframeUrl = $response->getIframeUrl()->addQueryParam('soundBlock', implode(',', $disabledVoices))->get();

        $firstVoice = $response->getVoicesActing()
            ->removeFromList($disabledVoices)
            ->getVoiceActingByPriority($ccdnConf->getJsonDecode('video_voice_priority'));

        $categoryPost = new PostCategories();
        $categoryPostArr = $categoryPost->make($ccdnConf, $response);

        $post = new Post();

        $post->title = $response->getName();
        $post->metatitle = $response->getName();
        $post->alt_name = URLify::filter($response->getName(), 190);
        $post->date = date('Y-m-d H:i:s');
        $post->autor = $member_id['name'];
        $post->approve = $ccdnConf->new_franchise_approve;
        $post->category = $categoryPostArr->implode();
        $post->allow_comm = $config['allow_comments'];
        $post->allow_main = '1';

        if ($ccdnConf->new_franchise_description === '1') {
            $post->full_story = $response->getDescription();
        }

        if ($ccdnConf->new_franchise_short_desc === '1') {
            $post->short_story = $response->getDescription();
        }

        if ($config['create_metatags'] === '1' && $ccdnConf->new_franchise_description === '1') {
            $meta = create_metatags($response->getDescription());
            $post->descr = $meta['description'];
            $post->keywords = $meta['keywords'];
        }

        $premierFormatDate = !empty($ccdnConf->premier_format_date) ? $ccdnConf->premier_format_date : 'Y-m-d';
        $iframeUrl = $ccdnConf->content_ads_filter === '1' && $response->getAds() ? '' : $iframeUrl;
        $post->setField($ccdnConf->episode_count_field, $response->getSeasons()->getAllEpisodesCount());
        $post->setField($ccdnConf->post_status_field, '1');
        $post->setField($ccdnConf->new_franchise_origin_name, $response->getNameEng());
        $post->setField($ccdnConf->new_franchise_poster, $response->getPoster());
        $post->setField($ccdnConf->new_franchise_year, $response->getYear());
        $post->setField($ccdnConf->new_franchise_country, $response->getCountries()->implode());
        $post->setField($ccdnConf->new_franchise_director, $response->getDirectors()->implode());
        $post->setField($ccdnConf->new_franchise_actors, $response->getActors()->implode());
        $post->setField($ccdnConf->video_voice_field,
            $response->getVoicesActing()->removeFromList($disabledVoices)->implode());
        $post->setField($ccdnConf->video_first_voice_field, $firstVoice);
        $post->setField($ccdnConf->new_franchise_age, $response->getAge());
        $post->setField($ccdnConf->new_franchise_time, $response->getTime());
        $post->setField($ccdnConf->new_franchise_premier,
            langdate($premierFormatDate, strtotime($response->getPremier())));
        $post->setField($ccdnConf->new_franchise_premier_rus,
            langdate($premierFormatDate, strtotime($response->getPremierRus())));
        $post->setField($ccdnConf->new_franchise_genres, $response->getGenres()->implode());
        $post->setField($ccdnConf->video_quality_field, $response->getQuality());
        $post->setField($ccdnConf->imdb_id_field, $response->getImdbId());
        $post->setField($ccdnConf->world_art_id_field, $response->getWorldArtId());
        $post->setField($ccdnConf->kinopoisk_id_field, $response->getKinopoiskId());
        $post->setField($ccdnConf->new_franchise_rating_imdb, $response->getImdbRating());
        $post->setField($ccdnConf->new_franchise_rating_kinopoisk, $response->getKinopoiskRating());
        $post->setField($ccdnConf->new_franchise_rating_world_art, $response->getWorldArtRating());
        $post->setField($ccdnConf->new_franchise_trailer, $response->getTrailers()->getLast()->getIframeUrl()->get());
        $post->setField($ccdnConf->embed_field, $iframeUrl);
        $post->setField($ccdnConf->serial_season_field, $season);
        $post->setField($ccdnConf->serial_episode_field, $episode);
        $post->setField($ccdnConf->ccdn_id_field, $response->getId());
        $post->setField($ccdnConf->collaps_franchise_ads_status_field, (int)$response->getAds());
        $post->setField($ccdnConf->season_franchise_status, $response->getSerialStatus()->toCyrillic());

        $post->setField($ccdnConf->new_franchise_name, $response->getName());
        $post->setField($ccdnConf->new_franchise_slogan, $response->getSlogan());
        $post->setField($ccdnConf->new_franchise_screenwriter, $response->getScreenwriters()->implode());
        $post->setField($ccdnConf->new_franchise_producer, $response->getProducers()->implode());
        $post->setField($ccdnConf->new_franchise_operator, $response->getOperators()->implode());
        $post->setField($ccdnConf->new_franchise_composer, $response->getComposers()->implode());
        $post->setField($ccdnConf->new_franchise_design, $response->getDesigns()->implode());
        $post->setField($ccdnConf->new_franchise_editor, $response->getEditors()->implode());
        $post->setField($ccdnConf->new_franchise_actors_dubbing, $response->getActorsDuplicators()->implode());
        $post->setField($ccdnConf->new_franchise_budget, $response->getBudget());
        $post->setField($ccdnConf->new_franchise_fees_use, $response->getFeesUSA());
        $post->setField($ccdnConf->new_franchise_fees_rus, $response->getFeesRus());
        $post->setField($ccdnConf->new_franchise_fees_world, $response->getFeesWorld());
        $post->setField($ccdnConf->new_franchise_rate_mpaa, $response->getRateMPAA());
        $post->setField($ccdnConf->new_franchise_trivia, $response->getTrivia()->implode("\n\n"));
        $post->setField($ccdnConf->new_franchise_filed_description, $response->getDescription());
        $post->setField($ccdnConf->collection_field, $response->getCollection()->implode());
        $post->setField($ccdnConf->new_franchise_franchise_type, $response->getType()->getName());

        if ($response->getType()->isSeasons()) {
            $post->title = SeasonsFranchiseTitle::handler($ccdnConf, $response, $post);
            $post->alt_name = SeasonsFranchiseAltUrl::handler($ccdnConf, $response, $post);
            $post->metatitle = SeasonsFranchiseMetaTitle::handler($ccdnConf, $response, $post);
        } else {
            $post->title = NotSeasonsFranchiseTitle::handler($ccdnConf, $response, $post);
            $post->alt_name = NotSeasonsFranchiseAltUrl::handler($ccdnConf, $response, $post);
            $post->metatitle = NotSeasonsFranchiseMetaTitle::handler($ccdnConf, $response, $post);
        }

        if ($config['create_catalog'] === '1') {
            $post->symbol = $post->getDb()->safesql(dle_substr(htmlspecialchars(strip_tags(stripslashes(trim($post->title))),
                ENT_QUOTES, $config['charset']), 0, 1, $config['charset']));
        }

        $insertPostCondition = $post->insertPost($categoryPostArr->toArray());

        if (!empty($ccdnConf->new_franchise_download_poster) && $response->getPoster() !== null) {
            $result = CCDNUploadPoster::upload($ccdnConf, $response, $post->id);
            if (!empty($result['xfvalue'])) {
                $post->setField($ccdnConf->new_franchise_download_poster, $result['xfvalue']);
                $post->setField($ccdnConf->new_franchise_download_poster_url, '/uploads/posts/' . $result['xfvalue']);
                $post->setField($ccdnConf->new_franchise_download_poster_url_with_domain,
                    Url::getDomain() . '/uploads/posts/' . $result['xfvalue']);
                $post->updatePost();
            }
        }

        return Response::json([
            'status' => $insertPostCondition ? 'ok' : 'Insert error',
            'item' => [
                'collaps_id' => $response->getId(),
                'name' => $response->getName(),
            ],
            'upload' => $result
        ]);
    }

    /**
     * @param Request $request
     * @return bool|string
     * @throws CCDNException
     */
    public function getFranchiseDetails(Request $request)
    {
        $id = $request->get('kinopoisk_id');
        $api = new ApiHandler();
        $response = $api->getFranchiseDetails([
            'kinopoisk_id' => $id,
        ]);

        if ($response === null) {
            throw new CCDNException("Not found. Kinopoisk id: {$id}", 404);
        }

        $model = new Model();
        $kinopoiskIdField = Settings::get('kinopoisk_id_field');

        $query = "SELECT * FROM (SELECT id,
 SUBSTRING_INDEX(SUBSTRING_INDEX(xfields, '{$kinopoiskIdField}|', -1), '|', 1) AS kinopoisk_id
 FROM `{$model->getPrefix()}_post`) as t WHERE t.kinopoisk_id = {$model->getDb()->safesql($id)}";

        if ($rawPost = $model->select($query)) {
            $response->addField('has_in_db', true);
            $response->addField('post_url', Url::toAdminPanel() . "?mod=editnews&action=editnews&id={$rawPost['id']}");
        } else {
            $response->addField('has_in_db', false);
        }

        $response->updateField('type', $response->getType()->getName());

        return Response::json($response->getData());
    }
}
