<?php

namespace App\Http\Controllers\Admin\Board\Board;

use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Validator;
use App\Http\Controllers\Controller;
use App\Models\Board;
use App\Models\BoardMeta;
use App\Models\BoardGroup;
use App\Models\DTO\SearchData;
use App\Models\DTO\ResponseData;
use Exception;

class ListController extends Controller
{
    private Board $boardModel;
    private BoardMeta $boardMetaModel;
    private BoardGroup $boardGroupModel;

    public function __construct(Board $board, BoardMeta $boardMeta, BoardGroup $boardGroup)
    {
        $this->boardModel = $board;
        $this->boardMetaModel = $boardMeta;
        $this->boardGroupModel = $boardGroup;
    }

    /**
     * 게시판 관리
     * @method GET
     * @see /admin/board/board/list
     */
    public function index(Request $request)
    {
        $params = SearchData::fromRequest($request);
        $boardData = $this->boardModel->data($params);

        if ($boardData->rows > 0) {
            $num = listNum($boardData->total,$params->page, $params->perPage);
            foreach ($boardData->list as $i => $row) {
                $row->num = $num--;
                $row->postRows = number_format($row->postRows);
                $row->commentRows = number_format($row->commentRows);
                $row->editURL = route('admin.board.board.list.show', $row->id);

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

        return view('admin.board.board.list', [
            'boardGroupData' => $this->boardGroupModel->all(),
            'boardData' => $boardData,
            'params' => $params
        ]);
    }

    /**
     * 게시판 수정 - 기본
     * @method GET
     * @see /admin/board/board/list/{pk}
     */
    public function show(int $boardID)
    {
        return view('admin.board.board.basic', [
            'actionURL' => route('admin.board.board.list.update', $boardID),
            'boardData' => $this->boardModel->find($boardID),
            'boardMetaData' => $this->boardMetaModel->getAllMeta($boardID),
            'boardAllData' => $this->boardModel->all(), // 모든 게시판
            'boardGroupData' => $this->boardGroupModel->all(), // 게시판 그룹
            'boardID' => $boardID
        ]);
    }

    /**
     * 게시판 등록
     * @method GET
     * @see /admin/board/board/create
     */
    public function create()
    {
        return view('admin.board.board.basic', [
            'actionURL' => route('admin.board.board.list.store'),
            'boardData' => [],
            'boardMetaData' => [],
            'boardAllData' => $this->boardModel->all(), // 모든 게시판
            'boardGroupData' => $this->boardGroupModel->all(), // 게시판 그룹
            'boardID' => null
        ]);
    }

    /**
     * 게시판 등록 저장
     * @method POST
     * @see /admin/board/board/list
     */
    public function store(Request $request, ResponseData $response)
    {
        $rules = [
            'code' => [
                'required',
                'string',
                'min:3',
                'max:50',
                'alpha_dash',
            ],
            'name' => 'required|max:255',
            'board_group_id' => 'required|exists:tb_board_group,id',
            'pc_header_content' => 'string|nullable|max:4000',
            'pc_footer_content' => 'string|nullable|max:4000',
            'mobile_header_content' => 'string|nullable|max:4000',
            'mobile_footer_content' => 'string|nullable|max:4000',
            'sort' => 'required|numeric',
            'is_search' => 'required|numeric|in:0,1',
            'is_display' => 'required|numeric|in:0,1',
            'use_inform_modal' => 'required|numeric|in:0,1',
            'inform_content' => 'string|nullable'
        ];

        $attributes = [
            'code' => '주소',
            'name' => '제목',
            'board_group_id' => '그룹 PK',
            'pc_header_content' => 'PC 상단 내용',
            'pc_footer_content' => 'PC 하단 내용',
            'mobile_header_content' => '모바일 상단 내용',
            'mobile_footer_content' => '모바일 하단 내용',
            'sort' => '순서',
            'is_search' => '검색 여부',
            'is_display' => '사용 여부',
            'use_inform_modal' => '이용안내 표시',
            'inform_content' => '이용안내 내용'
        ];

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

        $result = $this->boardModel->register($request, $response);

        if(!$result->success) {
            return back()->withErrors($result->message)->withInput();
        }

        $message = '게시판이 등록되었습니다.';
        return redirect()->route('admin.board.board.list.index')->with('message', $message);
    }

    /**
     * 게시판 수정 저장
     * @method PUT
     * @see /admin/board/board/list/{pk}
     */
    public function update(Request $request, ResponseData $response)
    {
        $boardID = $request->post('board_id');

        $rules = [
            'board_id' => 'required|numeric|exists:tb_board,id',
            'code' => [
                'required',
                'string',
                'min:3',
                'max:50',
                'alpha_dash',
                Rule::unique('tb_board', 'code')->ignore($boardID, 'id')
            ],
            'name' => 'required|max:255',
            'board_group_id' => 'required|exists:tb_board_group,id',
            'pc_header_content' => 'string|nullable',
            'pc_footer_content' => 'string|nullable',
            'mobile_header_content' => 'string|nullable',
            'mobile_footer_content' => 'string|nullable',
            'sort' => 'required|numeric',
            'is_search' => 'required|numeric|in:0,1',
            'is_display' => 'required|numeric|in:0,1',
            'use_inform_modal' => 'required|numeric|in:0,1',
            'inform_content' => 'string|nullable'
        ];

        $attributes = [
            'board_id' => 'PK',
            'code' => '주소',
            'name' => '제목',
            'board_group_id' => '그룹 PK',
            'pc_header_content' => 'PC 상단 내용',
            'pc_footer_content' => 'PC 하단 내용',
            'mobile_header_content' => '모바일 상단 내용',
            'mobile_footer_content' => '모바일 하단 내용',
            'sort' => '순서',
            'is_search' => '검색 여부',
            'is_display' => '사용 여부',
            'use_inform_modal' => '이용안내 표시',
            'inform_content' => '이용안내 내용'
        ];

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

        $result = $this->boardModel->updater($boardID, $request, $response);

        if(!$result->success) {
            return back()->withErrors($result->message)->withInput();
        }

        $message = '게시판이 수정되었습니다.';
        return redirect()->route('admin.board.board.list.show', $boardID)->with('message', $message);
    }

    /**
     * 게시판 선택 수정
     * @method PUT
     * @see /admin/board/board/list
     */
    public function listUpdate(Request $request)
    {
        $posts = $request->all();

        if($posts['chk']) {
            foreach($posts['chk'] as $boardID) {
                $updateData = [
                    'code' => ($posts['code'][$boardID] ?? ''),
                    'name' => ($posts['name'][$boardID] ?? ''),
                    'board_group_id' => ($posts['board_group_id'][$boardID] ?? ''),
                    'sort' => ($posts['sort'][$boardID] ?? '0'),
                    'is_search' => ($posts['is_search'][$boardID] ?? '0'),
                    'is_display' => ($posts['is_display'][$boardID] ?? '0'),
                ];

                $rules = [
                    'code' => [
                        'required',
                        'string',
                        'min:3',
                        'max:50',
                        'alpha_dash',
                        Rule::unique('tb_board', 'code')->ignore($boardID, 'id')
                    ],
                    'name' => 'required|max:255',
                    'board_group_id' => 'required|exists:tb_board_group,id',
                    'sort' => 'required|numeric',
                    'is_search' => 'required|numeric|in:0,1',
                    'is_display' => 'required|numeric|in:0,1'
                ];

                $attributes = [
                    'code' => '주소',
                    'name' => '제목',
                    'board_group_id' => '그룹 PK',
                    'sort' => '순서',
                    'is_search' => '검색 여부',
                    'is_display' => '사용 여부'
                ];

                $validator = Validator::make($updateData, $rules, [], $attributes);
                if($validator->fails()) {
                    return back()->withErrors($validator)->withInput();
                }

                $this->boardModel->find($boardID)->update($updateData);
            }
        }

        $message = '게시판 정보가 변경되었습니다.';
        return redirect()->route('admin.board.board.list.index')->with('message', $message);
    }

    /**
     * 게시판 삭제
     * @method DELETE
     * @see /admin/board/board/list/destroy
     */
    public function destroy(Request $request)
    {
        try{

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

            if ($chk) {
                foreach ($chk as $boardID) {
                    $board = $this->boardModel->findOrNew($boardID);

                    if (!$board->exists) {
                        throw new Exception($boardID . '번 게시판은 존재하지 않습니다.');
                    }

                    if ($board->post->count() > 0) {
                        return back()->withErrors($boardID . "번 게시판은 삭제할 수 없습니다.")->withInput();
                    }

                    $this->boardModel->remove($boardID);
                }
            }

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