<?php

namespace App\Http\Controllers\Admin\Page\Banner;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Banner;
use App\Models\BannerGroup;
use App\Models\DTO\SearchData;
use Exception;

class ListController extends Controller
{
    private Banner $bannerModel;
    private BannerGroup $bannerGroupModel;

    public function __construct(Banner $banner, BannerGroup $bannerGroup)
    {
        $this->bannerModel = $banner;
        $this->bannerGroupModel = $bannerGroup;
    }

    /**
     * 배너 관리
     * @method GET
     * @see /admin/page/banner
     */
    public function index(Request $request)
    {
        $params = SearchData::fromRequest($request);
        $params->activated =  $request->get('activated');

        $bannerData = $this->bannerModel->data($params);

        if($bannerData->total > 0) {
            $num = listNum($bannerData->total, $params->page, $params->perPage);
            foreach($bannerData->list as $i => $row) {
                $row->num = $num--;
                $row->creater = $row->user->find($row->user_id);
                $row->updater = $row->user->find($row->updated_user_id);
                $row->editURL = route('admin.page.banner.edit', $row->id);

                $bannerData->list[$i] = $row;
            }
        }

        return view('admin.page.banner.index', [
            'bannerData' => $bannerData,
            'params' => $params
        ]);
    }

    /**
     * 배너 등록
     * @method GET
     * @see /admin/page/banner
     */
    public function create()
    {
        return view('admin.page.banner.write', [
            'actionURL' => route('admin.page.banner.store'),
            'bannerGroupData' => $this->bannerGroupModel->all(),
            'bannerData' => [],
            'bannerID' => null
        ]);
    }

    /**
     * 배너 수정
     * @method GET
     * @see /admin/page/banner/{pk}/edit
     */
    public function edit(int $bannerID)
    {
        return view('admin.page.banner.write', [
            'actionURL' => route('admin.page.banner.update', $bannerID),
            'bannerGroupData' => $this->bannerGroupModel->all(),
            'bannerData' => $this->bannerModel->find($bannerID),
            'bannerID' => $bannerID
        ]);
    }

    /**
     * 배너 등록 저장
     * @method POST
     * @see /admin/page/banner
     */
    public function store(Request $request)
    {
        $rules = [
            'banner_group_id' => 'required|numeric|exists:tb_banner_group,id',
            'image' => 'image|max:3192',
            'subject' => 'nullable|string|max:50',
            'summary' => 'nullable|string|max:255',
            'start_date' => 'required|date',
            'end_date' => 'required|date',
            'url' => 'nullable|string',
            'target' => 'required|numeric|in:0,1',
            'device' => 'required|numeric|in:0,1,2',
            'width' => 'required|numeric',
            'height' => 'required|numeric',
            'order' => 'required|numeric',
            'activated' => 'required|numeric'
        ];

        $attributes = [
            'banner_group_id' => '위치',
            'image' => '이미지',
            'subject' => '제목',
            'summary' => '요약 설명',
            'start_date' => '시작일',
            'end_date' => '종료일',
            'url' => 'URL',
            'target' => '새창 여부',
            'device' => '표시기기',
            'width' => '가로 크기',
            'height' => '세로 크기',
            'order' => '정렬',
            'activated' => '활성화 여부'
        ];

        $posts = $this->validate($request, $rules, [], $attributes);

        $saveData = [
            'banner_group_id' => $posts['banner_group_id'],
            'user_id' => UID,
            'start_date' => $posts['start_date'],
            'end_date' => $posts['end_date'],
            'subject' => $posts['subject'],
            'summary' => $posts['summary'],
            'url' => $posts['url'],
            'target' => $posts['target'],
            'device' => $posts['device'],
            'width' => $posts['width'],
            'height' => $posts['height'],
            'views' => 0,
            'order' => $posts['order'],
            'activated' => $posts['activated'],
            'ip_address' => IP_ADDRESS,
            'user_agent' => USER_AGENT,
            'updated_user_id' => null,
            'updated_at' => null,
            'created_at' => now()
        ];

        // 파일 저장
        if($request->hasFile('image')) {
            $siteFavicon = $request->file('image');
            $siteFavicon->store(UPLOAD_PATH_PUBLIC . DIRECTORY_SEPARATOR . UPLOAD_PATH_BANNER);
            $saveData['image'] = (UPLOAD_PATH_STORAGE . DIRECTORY_SEPARATOR . UPLOAD_PATH_BANNER . DIRECTORY_SEPARATOR .$siteFavicon->hashName());
        }

        // 파일 삭제
        if($request->get('image_del')) {
            $path = $request->get('image_url');
            if(file_exists($path)) {
                unlink($request->get('image_url'));
            }
            $saveData['image'] = null;
        }

        $this->bannerModel->insert($saveData);

        $message = '배너가 새로 등록되었습니다.';
        return redirect()->route('admin.page.banner.index')->with('message', $message);
    }

    /**
     * 배너 수정 저장
     * @method PUT
     * @see /admin/page/banner/{pk}
     */
    public function update(Request $request)
    {
        $rules = [
            'banner_id' => 'required|numeric|exists:tb_banner,id',
            'banner_group_id' => 'required|numeric|exists:tb_banner_group,id',
            'image' => 'mimes:jpg,jpeg,gif,png|max:3192',
            'subject' => 'nullable|string|max:50',
            'summary' => 'nullable|string|max:255',
            'start_date' => 'required|date',
            'end_date' => 'required|date',
            'url' => 'nullable|string',
            'target' => 'required|numeric|in:0,1',
            'device' => 'required|numeric|in:0,1,2',
            'width' => 'required|numeric',
            'height' => 'required|numeric',
            'order' => 'required|numeric',
            'activated' => 'required|numeric'
        ];

        $attributes = [
            'banner_id' => '번호',
            'banner_group_id' => '위치',
            'image' => '이미지',
            'subject' => '제목',
            'summary' => '요약 설명',
            'start_date' => '시작일',
            'end_date' => '종료일',
            'url' => 'URL',
            'target' => '새창 여부',
            'device' => '표시기기',
            'width' => '가로 크기',
            'height' => '세로 크기',
            'order' => '정렬',
            'activated' => '활성화 여부'
        ];

        $posts = $this->validate($request, $rules, [], $attributes);

        $saveData = [
            'banner_group_id' => $posts['banner_group_id'],
            'start_date' => $posts['start_date'],
            'end_date' => $posts['end_date'],
            'subject' => $posts['subject'],
            'summary' => $posts['summary'],
            'url' => $posts['url'],
            'target' => $posts['target'],
            'device' => $posts['device'],
            'width' => $posts['width'],
            'height' => $posts['height'],
            'order' => $posts['order'],
            'activated' => $posts['activated'],
            'ip_address' => IP_ADDRESS,
            'user_agent' => USER_AGENT,
            'updated_user_id' => UID,
            'updated_at' => now()
        ];

        // 파일 저장
        if($request->hasFile('image')) {
            $siteFavicon = $request->file('image');
            $siteFavicon->store(UPLOAD_PATH_PUBLIC . DIRECTORY_SEPARATOR . UPLOAD_PATH_BANNER);
            $saveData['image'] = (UPLOAD_PATH_STORAGE . DIRECTORY_SEPARATOR . UPLOAD_PATH_BANNER . DIRECTORY_SEPARATOR . $siteFavicon->hashName());
        }

        // 파일 삭제
        if($request->get('image_del')) {
            $path = $request->get('image_url');
            if(file_exists($path)) {
                unlink($request->get('image_url'));
            }
            $saveData['image'] = null;
        }

        $this->bannerModel->find($posts['banner_id'])->update($saveData);

        $message = '배너 정보가 수정되었습니다.';
        return redirect()->route('admin.page.banner.edit', $posts['banner_id'])->with('message', $message);
    }

    /**
     * 배너 삭제
     * @method DELETE
     * @see /admin/page/banner
     */
    public function destroy(Request $request)
    {
        try {

            $chk = $request->post('chk');

            if ($chk) {
                foreach ($chk as $bannerID) {
                    $banner = $this->bannerModel->findOrNew($bannerID);

                    if (!$banner->exists) {
                        throw new Exception($bannerID . "번 배너는 존재하지 않습니다.");
                    }

                    // 이미지 삭제
                    if (file_exists($banner->image)) {
                        unlink($banner->image);
                    }

                    $banner->delete();
                }
            }

            $message = '배너 정보가 삭제되었습니다.';
            return redirect()->route('admin.page.banner.index')->with('message', $message);
        } catch (Exception $e) {
            return back()->withErrors($e->getMessage())->withInput();
        }
    }
}
