<?php

/*
 * DeckPHP V3 完全去混淆可读版
 * 原文件创建时间：2025-10-02 18:52:40
 * 说明：已移除 Hex/Base64/zlib/pack、字符串表、垃圾变量、随机标签和 goto。
 * 本文件按解密源码的实际控制流重写，未主动修正原有业务逻辑。
 */

namespace app\controller;

use think\facade\Config;
use think\facade\Cache;
use app\model\Users;
use app\model\Player;
use app\model\Song;
use app\model\Plays;
use app\model\PlayerSongSheet;

class Api extends Common
{
    /** 清除所有缓存。 */
    public function clearCache()
    {
        if (!Cache::clear()) {
            return json([
                'code' => -1,
                'msg'  => '清除缓存失败',
            ]);
        }

        return json([
            'code' => 0,
            'msg'  => '成功清除所有缓存',
        ]);
    }

    /** 返回播放器配置和歌单，响应格式为 JSONP。 */
    public function playerinfo()
    {
        $act = input('get.');
        $id = $act['id'];

        if (!$id || Player::checkPlayerKey($id) != 0) {
            return json(['code' => -1]);
        }

        $player = Player::where('id', $id)->find();

        Player::where('id', '=', $id)
            ->data([
                'plays'   => $player['plays'] + 1,
                'endtime' => date('Y-m-d H:i:s'),
            ])
            ->update();

        Plays::add([
            'player_id'  => $id,
            'user_id'    => $player['user_id'],
            'side'       => 'ios',
            'create_time'=> date('Y-m-d H:i:s'),
        ]);

        $cache = Cache::get('info' . $id);
        if ($cache) {
            return response($act['jsoncallback'] . '(' . $cache . ')');
        }

        $songSheetList = [];
        $songSheets = PlayerSongSheet::alias('pss')
            ->join('song_sheet ss', 'ss.id=pss.song_sheet_id')
            ->field('ss.*')
            ->where('pss.player_id', $id)
            ->order('pss.taxis asc')
            ->select();

        foreach ($songSheets as $key => $item) {
            $songs = Song::where('song_sheet_id', $item['id'])
                ->order('taxis asc')
                ->select();

            $songList = [];
            foreach ($songs as $songKey => $song) {
                $songList[$songKey] = [
                    'type'   => $song['type'],
                    'id'     => $song['song_id'],
                    'name'   => $song['name'],
                    'cover'  => $song['album_cover'],
                    'artist' => $song['artist_name'],
                    'album'  => $song['album_name'],
                    'url'    => $song['location'],
                    'lyric'  => $song['lyric'],
                ];
            }

            $songSheetList[$key] = [
                'SheetName' => $item['name'],
                'author'    => $item['author'],
                'songs'     => $songList,
            ];
        }

        $result = json_encode([
            'playerName'   => $player['name'],
            'showGreeting' => $player['show_greeting'],
            'switchopen'   => $player['switchopen'],
            'time'         => $player['time'],
            'showLrc'      => $player['show_lrc'],
            'showMsg'      => $player['showmsg'],
            'defaultAlbum' => $player['default_album'],
            'randomPlayer' => $player['random_player'],
            'defaultVolume'=> $player['default_volume'],
            'greeting'     => $player['greeting'],
            'autoPlayer'   => $player['auto_player'],
            'Sheetlist'    => $songSheetList,
            'showNotes'    => $player['show_notes'],
        ]);

        Cache::set('info' . $id, $result);
        return response($act['jsoncallback'] . '(' . $result . ')');
    }

    /** 获取歌曲播放地址并重定向。 */
    public function musicUrl()
    {
        $data = input('get.');

        // 原代码只检查 sign 是否存在，没有验证 sign 的内容。
        if (!isset($data['sign'], $data['songId'], $data['type'], $data['id'])) {
            return abort(400, 'Invalid sign');
        }

        $type = $data['type'];
        $songId = $data['songId'];

        $authJson = send_get(
            'https://auth.cenguigui.cn/MusicApi.php?qq=' . Config::get('api.qq')
            . '&skey=' . Config::get('api.skey')
            . '&demo=' . $_SERVER['SERVER_NAME']
        );
        $auth = json_decode($authJson, true);

        if ($auth['status'] != 'error') {
            $json = send_get(
                Config::get('api.music')
                . '?input=' . $songId
                . '&filter=id&type=' . $type
                . '&page=1&url=' . $_SERVER['SERVER_NAME']
            );
            $musicData = json_decode($json, true);
            $url = $musicData['url'];
        } elseif ($auth['message'] == '域名未授权') {
            $url = 'https://cdn.cenguigui.cn/Api/tts/2024-12-14-185658_111237.mp3';
        } elseif ($auth['message'] == 'skey有误') {
            $url = 'https://cdn.cenguigui.cn/Api/tts/2024-12-14-190011_184063.mp3';
        } else {
            $url = 'https://cdn.cenguigui.cn/Api/tts/2024-12-14-172754_164037.mp3';
        }

        return redirect($url);
    }

    /**
     * 原代码中存在、但 musicUrl() 未调用的签名生成算法。
     */
    private function generateSign($songId, $timestamp)
    {
        $key = 'mqyybfqyyds';
        $baseString = $songId . ':' . $timestamp . ':' . $key;
        $charArray = [];

        for ($i = 0; $i < strlen($baseString); $i++) {
            $charCode = ord($baseString[$i]);
            $charCode = ($charCode + ($i % 7) * 3) ^ ($i % 5);
            $charArray[] = $charCode;
        }

        $hexString = '';
        foreach ($charArray as $number) {
            $hexString .= str_pad(dechex($number), 2, '0', STR_PAD_LEFT);
        }

        return strrev($hexString);
    }

    /** 去掉 URL 协议和路径，只返回主机名。 */
    private function getOriginalDomain($domain)
    {
        // 保留原代码的判断方式。含 http:// 时执行的也是去除 https://。
        if (strpos($domain, 'http://') !== false) {
            $domain = str_replace('https://', '', $domain);
        } else {
            $domain = str_replace('http://', '', $domain);
        }

        $parts = explode('/', $domain);
        return $parts[0];
    }

    /** 返回域名最后两段；两段以内则返回完整域名。 */
    private function getTopLevelDomain($domain)
    {
        $parts = explode('.', $domain);
        if (count($parts) > 2) {
            return implode('.', array_slice($parts, -2));
        }

        return implode('.', $parts);
    }

    /** 获取歌词或 KSC 内容，以 JSONP 返回。 */
    public function musicLyric()
    {
        $data = input('get.');

        // 解密源码读取此缓存但不使用，保留有效写缓存行为。
        $unusedCache = Cache::get('musicLyric' . $data['type'] . $data['id']);

        if ($data['type'] == 'local') {
            $text = send_get($data['url']);
            $result = [
                'file' => 'null',
                'time' => date('Y-m-d h:i:s', time()),
                'type' => 'lrc',
                'txt'  => $text,
            ];
        } else {
            $player = Player::where('id', '=', $data['id'])->find();
            $userInfo = Users::where('uid', '=', $player['user_id'])->find();

            if ($userInfo['power'] == 2) {
                $result = $this->fetchLrcFromMusicApi($data);
            } elseif ($data['type'] == 'kugou') {
                $kscText = send_get(Config::get('api.getksc') . '?s=' . $data['songId']);

                if ($kscText == '') {
                    $result = $this->fetchLrcFromMusicApi($data);
                } else {
                    $result = [
                        'file' => Config::get('api.getksc') . '?s=' . $data['songId'],
                        'time' => date('Y-m-d h:i:s', time()),
                        'type' => 'ksc',
                        'txt'  => $kscText,
                    ];
                }
            } else {
                $ksc = isset($data['ksc']) ? $data['ksc'] : null;

                // 原代码调用 preg_replace() 后没有接收结果。
                preg_replace('# #', '', $ksc);
                $resourceExists = @file_get_contents($ksc, null, null, 0, 10);

                if ($resourceExists) {
                    $result = [
                        'file' => $ksc,
                        'time' => date('Y-m-d h:i:s', time()),
                        'type' => 'ksc',
                        'txt'  => send_get($ksc),
                    ];
                } else {
                    $result = $this->fetchLrcFromMusicApi($data);
                }
            }
        }

        Cache::set(
            'musicLyric' . $data['type'] . $data['id'],
            json_encode($result)
        );

        $json = json_encode($result);
        return response($data['jsoncallback'] . '(' . $json . ')');
    }

    /** musicLyric() 中重复出现的音乐 API 歌词请求。 */
    private function fetchLrcFromMusicApi(array $data)
    {
        $json = send_get(
            Config::get('api.music')
            . '?input=' . $data['songId']
            . '&filter=id&type=' . $data['type']
            . '&page=1&url=' . $_SERVER['SERVER_NAME']
        );
        $music = json_decode($json, true);

        return [
            'file' => 'null',
            'time' => date('Y-m-d h:i:s', time()),
            'type' => 'lrc',
            'txt'  => $music['lrc'],
        ];
    }

    /** 返回播放器封面主色及适配的字体颜色。 */
    public function mainColor()
    {
        $url = input('get.url');
        $cache = Cache::get('mainColor' . $url);

        if ($cache) {
            return response($cache);
        }

        $result = 'var cont =';

        if ($url !== null && $url !== '') {
            list($red, $green, $blue) = mainColor($url);
            $result .= "'{$red},{$green},{$blue}'";

            $grayLevel = $red * 0.299 + $green * 0.587 + $blue * 0.114;
            if ($grayLevel >= 150) {
                $result .= ";\nfont_color='0,0,0';\n";
            } else {
                $result .= ";\nfont_color='255,255,255';\n";
            }
        } else {
            $result .= "'0,0,0';\nfont_color='255,255,255';\n";
        }

        Cache::set('mainColor' . $url, $result);
        return $result;
    }

    /** 根据播放器主题动态返回播放器 JavaScript。 */
    public function PlayerJs($id)
    {
        $player = Player::where('id', '=', $id)->find();
        $user = Users::where('uid', '=', $player['user_id'])->find();
        $theme = $user['power'] == 2 ? 1 : $player['theme'];

        $filePath = getcwd()
            . '/static/guiloveyou/' . $theme
            . '/player/js12355555555/player.js';

        $playerIdScript = "var playerId = '{$id}';\n";
        $playerScriptContent = json_encode(file_get_contents($filePath));

        if ($player['jquery'] == 1) {
            $script = $playerIdScript . <<<'JAVASCRIPT'
var script = document.createElement("script");
script.src = "https://mirrors.sustech.edu.cn/cdnjs/ajax/libs/jquery/3.6.0/jquery.min.js";
script.onload = function() {
    loadPlayerScript();
};
document.head.appendChild(script);

function loadPlayerScript() {
    var playerScript = document.createElement("script");
    playerScript.textContent = PLAYER_SCRIPT_CONTENT;
    document.head.appendChild(playerScript);
}
JAVASCRIPT;
            $script = str_replace('PLAYER_SCRIPT_CONTENT', $playerScriptContent, $script);
        } else {
            $script = $playerIdScript
                . "var playerScript = document.createElement(\"script\");\n"
                . "playerScript..textContent = {$playerScriptContent};\n"
                . "document.head.appendChild(playerScript);";
        }

        return response($script)->contentType('application/javascript');
    }

    /** 重定向到播放器主题 CSS。 */
    public function PlayerCss($id)
    {
        $player = Player::where('id', '=', $id)->find();
        $user = Users::where('uid', '=', $player['user_id'])->find();
        $theme = $user['power'] == 2 ? 1 : $player['theme'];

        $url = get_domain()
            . 'static/guiloveyou/' . $theme
            . '/player/css/player.css';

        return redirect($url);
    }
}
