<?php

namespace App\Http\Controllers\Movie;

use Illuminate\Http\Request;
use Illuminate\Http\Client\ConnectionException;
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\CompanyParams;
use Exception;

class CompanyController extends Controller
{
    use CommonTrait;
    use PagingTrait;

    private string $host;

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

        $this->host = env('MOVIE_API');
    }

    /**
     * 영화사 목록
     * @method GET
     * @see /movie/company
     */
    public function index(Request $request, CompanyParams $params)
    {
        $rules = [
            'page' => 'nullable|numeric',
            'keyword' => 'nullable|string|max:100',
            'ceo' => 'nullable|string|max:30'
        ];

        $attributes = [
            'page' => '페이지 번호',
            'keyword' => '영화사명',
            'ceo' => '대표자명'
        ];

        $message = [
            'page.numeric' => '페이지 번호는 숫자여야 합니다.',
            'keyword.max' => '영화사명 최대 글자는 100자 입니다.',
            'ceo.max' => '대표자명 최대 글자는 30자 입니다.'
        ];

        // 검색 유효성 검사
        Validator::make($request->all(), $rules, $message, $attributes)->validated();

        $page = max(1, (int)$request->get('page', 1));
        $params->curPage = $page;
        $params->companyNm = $request->get('keyword');
        $params->ceoNm = $request->get('ceo');

        // 검색 조건 (crawler 장애 시 빈 목록으로 격리)
        $total = 0;
        $list = [];
        try {
            $response = Http::timeout(5)->get($this->host . COMPANY_LIST, $params->toArray());
        } catch (ConnectionException) {
            $response = null;
        }

        if ($response && $response->ok()) {
            $data = json_decode($response->body());
            $total = (int)($data->total ?? 0);
            if ($total > 0) {
                $queryString = $request->getQueryString();
                foreach ($data->list as $row) {
                    $row->viewURL = route('movie.company.show', base64_encode($row->companyCd));
                    if ($queryString) {
                        $row->viewURL .= ('?' . $queryString);
                    }
                    $list[] = $row;
                }
            }
        }

        $companies = $this->getPaginator($list, $total, $params->itemPerPage, $page);

        return view(layout('movie.company.index'), [
            'keyword' => $request->get('keyword'),
            'ceo' => $request->get('ceo'),
            'total' => $total,
            'companies' => $companies
        ]);
    }

    /**
     * 영화사 상세 보기
     * @method GET
     * @see /movie/company/{company_cd}
     */
    public function show(string $base64, Request $request, CompanyParams $params)
    {
        try {

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

            $companyCd = base64_decode($base64);

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

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

            // 검색 조건
            $params->companyCd = $companyCd;
            $response = Http::timeout(5)->get($this->host . COMPANY_INFO, $params->toArray());

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

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

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

            $companyNm = $info->companyNm;
            if(!empty($info->companyNmEn)) {
                $companyNm .= (' (' . $info->companyNmEn . ')');
            }

            return view(layout('movie.company.show'), [
                'companyNm' => $companyNm,
                'info' => $info,
                'listURL' => $listURL
            ]);

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