<?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\Http\Traits\PagingTrait;
use App\Models\DTO\Movie\ListParams;
use App\Models\DTO\Movie\InfoParams;
use App\Models\DTO\SearchData;
use App\Models\Movie\Movie;
use App\Models\Movie\MovieReview;
use Exception;

class SearchController extends Controller
{
    use CommonTrait;
    use PagingTrait;

    private string $host;
    private Movie $movieModel;
    private MovieReview $movieReviewModel;

    public function __construct(
        Movie $movieModel,
        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->movieModel = $movieModel;
        $this->movieReviewModel = $movieReviewModel;
    }

    /**
     * 영화 DB
     * @method GET
     * @see /movie/search
     */
    public function index(Request $request, ListParams $params)
    {
        $rules = [
            'page' => 'nullable|numeric',
            'keyword' => 'nullable|string|max:100',
            'director' => 'nullable|string|max:30',
            's_year' => 'nullable|date_format:Y|before:e_year',
            'e_year' => 'nullable|date_format:Y|after:s_year',
            's_open_dt' => 'nullable|date_format:Y-m-d|before:e_open_dt',
            'e_open_dt' => 'nullable|date_format:Y-m-d|after:s_open_dt',
            'genre' => 'nullable|numeric',
            'type' => 'nullable|numeric'
        ];

        $attributes = [
            'page' => '페이지 번호',
            'keyword' => '검색어',
            'director' => '감독',
            's_year' => '제작 시작연도',
            'e_year' => '제작 종료연도',
            's_open_dt' => '개봉 시작일',
            'e_open_dt' => '개봉 종료일',
            'genre' => '장르',
            'type' => '유형'
        ];

        $message = [
            'page.numeric' => '페이지 번호는 숫자여야 합니다.',
            'keyword.max' => '검색어 최대 글자는 100자 입니다.',
            's_year.date_format' => '제작 시작연도 형식이 옳지 않습니다.',
            's_year.before' => '제작 시작연도는 종료 연도보다 작아야 합니다.',
            'e_year.date_format' => '제작 시작연도 형식이 옳지 않습니다.',
            'e_year.after' => '제작 종료연도는 시작 연도보다 커야 합니다.',
            's_open_dt.date_format' => '개봉 시작일 형식이 옳지 않습니다.',
            's_open_dt.before' => '개봉 시작일은 종료일 보다 작아야 합니다.',
            'e_open_dt.date_format' => '개봉 종료일 형식이 옳지 않습니다.',
            'e_open_dt.after' => '개봉 종료일은 시작일 보다 커야 합니다.',
        ];

        // 검색 유효성 검사
        Validator::make($request->all(), $rules, $message, $attributes)->validated();
        $params = SearchData::fromRequest($request);
        $params->director = $request->get('director');
        $params->sYear = $request->get('s_year');
        $params->eYear = $request->get('e_year');
        $params->sOpenDt = $request->get('s_open_dt');
        $params->eOpenDt = $request->get('e_open_dt');
        $params->genre = $request->get('genre', []);
        $params->type = $request->get('type', []);
        $params->perPage = 20;

        $movies = $this->movieModel->list($params);
        if($movies->total > 0) {
            $queryString = $request->getQueryString();
            foreach($movies->list as &$row) {
                $row->open_dt = ($row->open_dt ? date('Y.m.d', strtotime($row->open_dt)) : null);
                $row->viewURL = route('movie.search.show', base64_encode($row->movie_cd));
                if($queryString) {
                    $row->viewURL .= ('?' . $queryString);
                }
            }
        }

        return view('movie.search.index', [
            'params' => $params,
            'movies' => $movies
        ]);
    }

    /**
     * 영화 DB 상세 보기
     * @method GET
     * @see /movie/search/{movie_id}
     */
    public function show(string $base64, Request $request, InfoParams $params)
    {
        try {

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

            $movieCd = base64_decode($base64);

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

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

            // 검색 조건
            $url = ($this->host . MOVIE_INFO);

            $params->movieCd = $movieCd;
            $response = Http::get($url, $params->toArray());

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

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

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

            $avgRate = $this->movieReviewModel->getAvgRate($movieCd);

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

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