<?php

namespace App\Http\Controllers\Movie;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Validator;
use App\Http\Controllers\Controller;
use App\Http\Traits\CommonTrait;
use App\Models\DTO\Movie\BoxOfficeParams;
use App\Models\DTO\Movie\InfoParams;
use App\Models\Movie\MovieReview;
use DateTime;
use Exception;

class RankController extends Controller
{
    use CommonTrait;

    private string $host;
    private MovieReview $movieReviewModel;

    public function __construct(MovieReview $movieReviewModel) {
        $this->middleware('front');

        if(env('APP_ENV') == "local") {
            $this->host = ('host.mysql.moview:1050');
        }else{
            $this->host = ('172.17.0.1:1050');
        }

        $this->movieReviewModel = $movieReviewModel;
    }

    /**
     * 영화 인기순위
     * @method GET
     * @see /movie/rank
     */
    public function index(Request $request, BoxOfficeParams $params)
    {
        $rules = [
            'date' => 'nullable|date_format:Y-m-d',
            'nation' => 'nullable|in:k,f'
        ];

        $attributes = [
            'date' => '기간',
            'nation' => '구분'
        ];

        $message = [
            'date.date_format' => '날짜 형식이 옳지 않습니다.',
            'nation.in' => '구분 형식이 옳지 않습니다.',
        ];

        // 검색 유효성 검사
        Validator::make($request->all(), $rules, $message, $attributes)->validated();
        $date = $request->get('date', now()->format('Y-m-d'));
        $nation = $request->get('nation', []);
        $dateTime = new DateTime($date);

        if ($dateTime->format('N') < 6) { // 평일
            $url = ($this->host . MOVIE_DAILY_LIST);
            if(now()->diffInDays($date) == 0) {
                $dateTime->modify('-1 day');
            }
        } else { // 주말
            $url = ($this->host . MOVIE_WEEK_LIST);
            $dateTime->modify('-7 day');
        }

        // 검색 기간
        $params->targetDt = $dateTime->format('Ymd');

        // 국가 구분 값 계산
        if($nation) {
            $nl = 0;
            foreach($nation as $n) {
                $n = strtolower($n);
                if($n == 'k') {
                    $params->repNationCd = 'K';
                    $nl++;
                }
                if($n == 'f') {
                    $params->repNationCd = 'F';
                    $nl++;
                }
            }
            if($nl == 2) {
                $params->repNationCd = '';
            }
        }

        // 검색 조건
        $response = Http::get($url, $params->toArray());

        $data = null;
        if($response->ok()) {
            $data = json_decode($response->body());
            if($data->total > 0) {
                $queryString = $request->getQueryString();
                foreach($data->list as $row) {
                    $row->OpenDt = date('Y.m.d', strtotime($row->OpenDt));
                    if(isset($row->DailyID)) {
                        $id = base64_encode($row->DailyID . '|daily');
                    }else{
                        $id = base64_encode($row->WeeklyID . '|weekly');
                    }
                    $row->viewURL = route('movie.rank.show', $id);
                    if($queryString) {
                        $row->viewURL .= ('?' . $queryString);
                    }
                }
            }
        }

        return view('movie.rank.index', [
            'data' => $data,
            'date' => $date,
            'nation' => $nation
        ]);
    }

    /**
     * 영화 인기순위 보기
     * @method GET
     * @see /movie/rank/{daily_id|weekly_id}
     */
    public function show(string $base64, Request $request, InfoParams $params)
    {
        try {

            if(!$base64) {
                throw new Exception('잘못된 접근입니다. [1]');
            }

            [$id, $type] = explode('|', base64_decode($base64));

            if(!$id || !$type) {
                throw new Exception('잘못된 접근입니다. [2]');
            }

            $listURL = route('movie.rank.index');
            if($queryString = $request->getQueryString()) {
                $listURL .= ('?' . $queryString);
            }

            // 검색 조건
            if($type == 'daily') {
                $url = ($this->host . MOVIE_DAILY_INFO);
            }else{
                $url = ($this->host . MOVIE_WEEKLY_INFO);
            }

            $params->{$type. 'ID'} = $id;
            $response = Http::get($url, $params->toArray());

            if(!$response->ok()) {
                throw new Exception('요청한 정보가 없습니다.');
            }

            $data = json_decode($response->body());
            $stats = $data->stats;
            $info = $data->info;
            $detail = $data->detail;

            $movieCd = base64_encode($info->MovieCd);
            $movieNm = $info->MovieNm;
            if($info->MovieNmEn) {
                $movieNm .= (' (' . $info->MovieNmEn . ')');
            }

            $avgRate = $this->movieReviewModel->getAvgRate($info->MovieCd);

            return view('movie.rank.show', [
                'movieCd' => $movieCd,
                'movieNm' => $movieNm,
                'stats' => $stats,
                'info' => $info,
                'detail' => $detail,
                'listURL' => $listURL,
                'avgRate' => $avgRate
            ]);

        }catch(Exception $e) {
            abort($e->getCode(), $e->getMessage());
        }
    }
}
