<?php

namespace App\Console\Anime;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use App\Services\AIGeneration\AIImageGenerationService;

class AnimeCheckImgUrlCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'Anime:checkImgUrl';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '检查动漫对话角色和场景图片生成状态';

    protected $aiImageGenerationService;

    public function __construct(AIImageGenerationService $aiImageGenerationService)
    {
        parent::__construct();
        $this->aiImageGenerationService = $aiImageGenerationService;
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        dLog('generate')->info('====================开始检查动漫对话角色和场景图片生成状态====================');
        $time_start = microtime(true);
        $timeout = 50; // 超时时间50秒
        $check_interval = 3; // 每3秒检查一次
        
        while (true) {
            // 检查是否超时
            $elapsed_time = microtime(true) - $time_start;
            if ($elapsed_time >= $timeout) {
                dLog('generate')->info('检查超时，退出循环');
                break;
            }

            // 检查是否有需要处理的数据
            $has_pending_animes = $this->hasPendingAnimes();
            $has_pending_episodes = $this->hasPendingEpisodes();

            // 如果没有需要检查的内容，直接跳出循环
            if (!$has_pending_animes && !$has_pending_episodes) {
                dLog('generate')->info('没有需要检查的内容，退出循环');
                break;
            }

            // 检查动漫全局角色和场景
            if ($has_pending_animes) {
                $this->checkAnimes();
            }

            // 检查剧集角色和场景
            if ($has_pending_episodes) {
                $this->checkEpisodes();
            }

            // 等待3秒后继续下一次检查
            sleep($check_interval);
        }

        $time_end = microtime(true);
        dLog('generate')->info('脚本执行时间: '.round($time_end-$time_start, 2).'秒');
        dLog('generate')->info('====================结束检查动漫对话角色和场景图片生成状态====================');
    }

    // 检查动漫全局执行中的任务
    private function hasPendingAnimes() {
        $time_expire_datetime = date('Y-m-d H:i:s', strtotime('-12 hours'));
        DB::table('mp_animes')->where('generate_status', '执行中')->where('generate_at', '<', $time_expire_datetime)->update([
            'generate_status' => '失败',
            'updated_at'=>date('Y-m-d H:i:s'),
        ]);

        return DB::table('mp_animes')->where('generate_status', '执行中')->exists();
    }

    // 检查剧集执行中的任务
    private function hasPendingEpisodes() {
        $time_expire_datetime = date('Y-m-d H:i:s', strtotime('-12 hours'));
        DB::table('mp_anime_episodes')->where('generate_status', '执行中')->where('generate_at', '<', $time_expire_datetime)->update([
            'generate_status' => '失败',
            'updated_at'=>date('Y-m-d H:i:s'),
        ]);

        return DB::table('mp_anime_episodes')->where('generate_status', '执行中')->exists();
    }

    // 检查全局
    private function checkAnimes() {
        dLog('generate')->info('====================开始检查动漫全局====================');

        // 获取待执行的动漫对话数据
        $data = DB::table('mp_animes')->where('generate_status', '执行中')->select('id', 'roles', 'scenes')->get();
        
        foreach ($data as $item) {
            $id = getProp($item, 'id');
            $roles = json_decode(getProp($item, 'roles'), true);
            $scenes = json_decode(getProp($item, 'scenes'), true);
            $role_count = count($roles);
            $scene_count = count($scenes);

            // 处理角色图片状态
            $role_result = $this->checkRoles($id, $roles);

            // 处理场景图片状态
            $scene_result = $this->checkScenes($id, $scenes);
            $scene_result['success_count'] = 6;

            if ($role_result['success_count'] == $role_count && $scene_result['success_count'] == $scene_count) {
                // 更新状态为已完成
                // DB::table('mp_animes')->where('id', $id)->update(['generate_status' => '已完成', 'updated_at'=>date('Y-m-d H:i:s')]);
                dLog('generate')->info('动漫对话图片已全部生成完毕');

                // 同步更新该动漫对话剧集的所有角色或场景
                $this->syncRolesAndScenes($id, $role_result['roles'], $scene_result['scenes']);
            }
        }

        dLog('generate')->info('====================结束检查动漫全局====================');
    }


    // 检查全局角色
    private function checkRoles($id, $roles) {
        $role_success_count = 0;
        foreach ($roles as &$role) {
            $task_id = getProp($role, 'task_id');
            $task_status = getProp($role, 'task_status');
            if (!$task_id || $task_status == 'success') {
                $role_success_count++;
                continue;
            }
            $task = DB::table('mp_generate_pic_tasks')->where('id', $task_id)->select('result_url', 'status')->first();
            if (in_array(getProp($task, 'status'), ['success', 'failed'])) {
                $role['task_status'] = 'success';
                $role['url'] = '';
                $result_url = getProp($task, 'result_url');
                if ($result_url && is_json($result_url)) {
                    $role['url'] = json_decode($result_url, true)[0];
                }

                $role_success_count++;
            }
        }

        if ($role_success_count > 0) {
            DB::table('mp_animes')->where('id', $id)->update(['roles' => json_encode($roles, 256)]);
        }

        return [
            'roles'         => $roles,
            'success_count' => $role_success_count,
        ];
    }

    // 检查全局场景
    private function checkScenes($id, $scenes) {
        $scene_success_count = 0;
        foreach ($scenes as &$scene) {
            $task_id = getProp($scene, 'task_id');
            $task_status = getProp($scene, 'task_status');
            if (!$task_id || $task_status == 'success') {
                $scene_success_count++;
                continue;
            }
            $task = DB::table('mp_generate_pic_tasks')->where('id', $task_id)->select('result_url', 'status')->first();
            if (in_array(getProp($task, 'status'), ['success', 'failed'])) {
                $scene['task_status'] = 'success';
                $scene['url'] = '';
                $result_url = getProp($task, 'result_url');
                if ($result_url && is_json($result_url)) {
                    $scene['url'] = json_decode($result_url, true)[0];
                }

                $scene_success_count++;
            }
        }

        if ($scene_success_count > 0) {
            DB::table('mp_animes')->where('id', $id)->update(['scenes' => json_encode($scenes, 256)]);
        }
        return [
            'scenes'        => $scenes,
            'success_count' => $scene_success_count,
        ];
    }

    // 剧集中同步继承全局角色和场景
    private function syncRolesAndScenes($id, $roles, $scenes) {
        // 获取该动漫对话对应的所有剧集
        $episodes = DB::table('mp_anime_episodes')->where('anime_id', $id)->get();
        
        if ($episodes->isEmpty()) {
            dLog('generate')->info("动漫对话ID:{$id} 没有关联的剧集");
            return;
        }

        foreach ($episodes as $episode) {
            $episode_id = getProp($episode, 'id');
            $episode_roles = json_decode(getProp($episode, 'roles'), true) ?: [];
            $episode_scenes = json_decode(getProp($episode, 'scenes'), true) ?: [];
            
            $roles_updated = false;
            $scenes_updated = false;

            // 更新剧集中的角色URL
            foreach ($episode_roles as &$episode_role) {
                $episode_role_name = getProp($episode_role, 'role');
                $episode_description = getProp($episode_role, 'description');
                $episode_url = getProp($episode_role, 'url');
                $episode_task_id = getProp($episode_role, 'task_id');

                // 如果已有URL或已有任务ID，跳过
                if (!empty($episode_url) || !empty($episode_task_id)) {
                    continue;
                }

                $url_inherited = false;

                // 遍历方法中的角色数据
                foreach ($roles as $role) {
                    $role_name = getProp($role, 'role');
                    $role_description = getProp($role, 'description');
                    $role_url = getProp($role, 'url');

                    // 满足三个条件：1.角色名相同 2.描述相同 3.剧集中URL为空且方法中URL不为空
                    if ($episode_role_name == $role_name 
                        && $episode_description == $role_description 
                        && empty($episode_url) 
                        && !empty($role_url)) {
                        $episode_role['url'] = $role_url;
                        $roles_updated = true;
                        $url_inherited = true;
                        dLog('generate')->info("剧集ID:{$episode_id} 角色:{$role_name} URL已更新");
                        break;
                    }
                }

                // 如果无法继承URL，则创建图片生成任务
                if (!$url_inherited && $episode_role_name != '旁白') {
                    try {
                        // 获取剧集的美术风格
                        $art_style = getProp($episode, 'art_style');
                        $description = $episode_description;
                        if ($art_style) {
                            $description = "美术风格：\n$art_style\n主体描述：$description";
                        }

                        $params = [
                            'prompt' => $description,
                            'ref_img_urls' => []
                        ];
                        
                        $task = $this->aiImageGenerationService->createImageGenerationTask($params);
                        $task_id = $task->id;
                        
                        if ($task_id) {
                            $episode_role['task_id'] = $task_id;
                            $episode_role['task_status'] = 'processing';
                            $roles_updated = true;
                            dLog('generate')->info("剧集ID:{$episode_id} 角色:{$episode_role_name} 创建图片生成任务，任务ID:{$task_id}");
                        }
                    } catch (\Exception $e) {
                        dLog('generate')->error("剧集ID:{$episode_id} 角色:{$episode_role_name} 创建图片生成任务失败: " . $e->getMessage());
                    }
                }
            }

            // 更新剧集中的场景URL
            foreach ($episode_scenes as &$episode_scene) {
                $episode_scene_name = getProp($episode_scene, 'scene');
                $episode_description = getProp($episode_scene, 'description');
                $episode_url = getProp($episode_scene, 'url');
                $episode_task_id = getProp($episode_scene, 'task_id');

                // 如果已有URL或已有任务ID，跳过
                if (!empty($episode_url) || !empty($episode_task_id)) {
                    continue;
                }

                $url_inherited = false;

                // 遍历方法中的场景数据
                foreach ($scenes as $scene) {
                    $scene_name = getProp($scene, 'scene');
                    $scene_description = getProp($scene, 'description');
                    $scene_url = getProp($scene, 'url');

                    // 满足三个条件：1.场景名相同 2.描述相同 3.剧集中URL为空且方法中URL不为空
                    if ($episode_scene_name == $scene_name 
                        && $episode_description == $scene_description 
                        && empty($episode_url) 
                        && !empty($scene_url)) {
                        $episode_scene['url'] = $scene_url;
                        $scenes_updated = true;
                        $url_inherited = true;
                        dLog('generate')->info("剧集ID:{$episode_id} 场景:{$scene_name} URL已更新");
                        break;
                    }
                }

                // 如果无法继承URL，则创建图片生成任务
                if (!$url_inherited) {
                    try {
                        // 获取剧集的美术风格
                        $art_style = getProp($episode, 'art_style');
                        $description = $episode_description;
                        if ($art_style) {
                            $description = "美术风格：\n$art_style\n场景描述：$description";
                        }

                        $params = [
                            'prompt' => $description,
                            'ref_img_urls' => []
                        ];
                        
                        $task = $this->aiImageGenerationService->createImageGenerationTask($params);
                        $task_id = $task->id;
                        
                        if ($task_id) {
                            $episode_scene['task_id'] = $task_id;
                            $episode_scene['task_status'] = 'processing';
                            $scenes_updated = true;
                            dLog('generate')->info("剧集ID:{$episode_id} 场景:{$episode_scene_name} 创建图片生成任务，任务ID:{$task_id}");
                        }
                    } catch (\Exception $e) {
                        dLog('generate')->error("剧集ID:{$episode_id} 场景:{$episode_scene_name} 创建图片生成任务失败: " . $e->getMessage());
                    }
                }
            }

            // 如果有更新，则保存到数据库
            if ($roles_updated || $scenes_updated) {
                $update_data = ['updated_at' => date('Y-m-d H:i:s')];
                
                if ($roles_updated) {
                    $update_data['roles'] = json_encode($episode_roles, 256);
                }
                
                if ($scenes_updated) {
                    $update_data['scenes'] = json_encode($episode_scenes, 256);
                }

                DB::table('mp_anime_episodes')->where('id', $episode_id)->update($update_data);
                dLog('generate')->info("剧集ID:{$episode_id} 数据已同步更新");
            }
        }
    }


    // 检查剧集
    private function checkEpisodes() {
        dLog('generate')->info('====================开始检查剧集====================');

        // 获取待执行的剧集数据
        $data = DB::table('mp_anime_episodes')->where('generate_status', '执行中')->select('id', 'roles', 'scenes')->get();
        
        foreach ($data as $item) {
            $id = getProp($item, 'id');
            $roles = json_decode(getProp($item, 'roles'), true);
            $scenes = json_decode(getProp($item, 'scenes'), true);
            $role_count = count($roles);
            $scene_count = count($scenes);

            // 处理角色图片状态
            $role_result = $this->checkEpisodeRoles($id, $roles);

            // 处理场景图片状态
            $scene_result = $this->checkEpisodeScenes($id, $scenes);

            if ($role_result['success_count'] == $role_count && $scene_result['success_count'] == $scene_count) {
                // 更新状态为已完成
                DB::table('mp_anime_episodes')->where('id', $id)->update(['generate_status' => '已完成', 'updated_at'=>date('Y-m-d H:i:s')]);
                dLog('generate')->info("剧集ID:{$id} 图片已全部生成完毕");
            }
        }

        dLog('generate')->info('====================结束检查剧集====================');
    }

    // 检查剧集角色
    private function checkEpisodeRoles($id, $roles) {
        $role_success_count = 0;
        foreach ($roles as &$role) {
            $task_id = getProp($role, 'task_id');
            $task_status = getProp($role, 'task_status');
            if (!$task_id || $task_status == 'success') {
                $role_success_count++;
                continue;
            }
            $task = DB::table('mp_generate_pic_tasks')->where('id', $task_id)->select('result_url', 'status')->first();
            if (in_array(getProp($task, 'status'), ['success', 'failed'])) {
                $role['task_status'] = 'success';
                $role['url'] = '';
                $result_url = getProp($task, 'result_url');
                if ($result_url && is_json($result_url)) {
                    $role['url'] = json_decode($result_url, true)[0];
                }

                $role_success_count++;
            }
        }

        if ($role_success_count > 0) {
            DB::table('mp_anime_episodes')->where('id', $id)->update(['roles' => json_encode($roles, 256)]);
        }

        return [
            'roles'         => $roles,
            'success_count' => $role_success_count,
        ];
    }

    // 检查剧集场景
    private function checkEpisodeScenes($id, $scenes) {
        $scene_success_count = 0;
        foreach ($scenes as &$scene) {
            $task_id = getProp($scene, 'task_id');
            $task_status = getProp($scene, 'task_status');
            if (!$task_id || $task_status == 'success') {
                $scene_success_count++;
                continue;
            }
            $task = DB::table('mp_generate_pic_tasks')->where('id', $task_id)->select('result_url', 'status')->first();
            if (in_array(getProp($task, 'status'), ['success', 'failed'])) {
                $scene['task_status'] = 'success';
                $scene['url'] = '';
                $result_url = getProp($task, 'result_url');
                if ($result_url && is_json($result_url)) {
                    $scene['url'] = json_decode($result_url, true)[0];
                }

                $scene_success_count++;
            }
        }

        if ($scene_success_count > 0) {
            DB::table('mp_anime_episodes')->where('id', $id)->update(['scenes' => json_encode($scenes, 256)]);
        }
        return [
            'scenes'        => $scenes,
            'success_count' => $scene_success_count,
        ];
    }
}