<?php

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

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\BoardGroup;
use App\Models\BoardGroupMeta;
use App\Models\DTO\SearchData;
use App\Models\DTO\ResponseData;
use Exception;

class ListController extends Controller
{
    private Board $boardModel;
    private BoardGroup $boardGroupModel;
    private BoardGroupMeta $boardGroupMetaModel;

    public function __construct(Board $board, BoardGroup $boardGroup, BoardGroupMeta $boardGroupMeta)
    {
        $this->boardModel = $board;
        $this->boardGroupModel = $boardGroup;
        $this->boardGroupMetaModel = $boardGroupMeta;
    }

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

        if ($boardGroupData->rows > 0) {
            $num = listNum($boardGroupData->total, $params->page, $params->perPage);
            foreach ($boardGroupData->list as $i => $row) {
                $row->num = $num--;
                $row->boardRows = number_format($row->boardRows);
                $row->postRows = number_format($row->postRows);
                $row->commentRows = number_format($row->commentRows);
                $row->createdAt = dateBr($row->created_at, '-');
                $row->editURL = route('admin.board.group.list.edit', $row->id);

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

        return view('admin.board.group.index', [
            'boardGroupData' => $boardGroupData,
            'params' => $params
        ]);
    }

    /**
     * 게시판 그룹 등록
     * @method GET
     * @see /admin/board/group/list/create
     */
    public function create()
    {
        return view('admin.board.group.write', [
            'actionURL' => route('admin.board.group.list.store'),
            'boardGroupData' => [],
            'boardGroupMetaData' => [],
            'boardGroupID' => null
        ]);
    }

    /**
     * 게시판 그룹 수정
     * @method GET
     * @see /admin/board/group/list/{pk}/edit
     */
    public function edit(int $boardGroupID)
    {
        return view('admin.board.group.write', [
            'actionURL' => route('admin.board.group.list.update', $boardGroupID),
            'boardGroupData' => $this->boardGroupModel->find($boardGroupID),
            'boardGroupMetaData' => $this->boardGroupMetaModel->getAllMeta($boardGroupID),
            'boardGroupID' => $boardGroupID
        ]);
    }

    /**
     * 게시판 그룹 등록 저장
     * @method POST
     * @see /admin/board/group/list
     */
    public function store(Request $request, ResponseData $response)
    {
        $rules = [
            'code' => [
                'required',
                'string',
                'min:3',
                'max:50',
                'alpha_dash',
            ],
            'name' => 'required|max:255',
            'sort' => 'required|numeric',
            'pc_header_content' => 'string|nullable',
            'pc_footer_content' => 'string|nullable',
            'mobile_header_content' => 'string|nullable',
            'mobile_footer_content' => 'string|nullable'
        ];

        $attributes = [
            'code' => '주소',
            'name' => '제목',
            'sort' => '순서',
            'pc_header_content' => 'PC 상단 내용',
            'pc_footer_content' => 'PC 하단 내용',
            'mobile_header_content' => '모바일 상단 내용',
            'mobile_footer_content' => '모바일 하단 내용'
        ];

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

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

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

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

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

        $rules = [
            'board_group_id' => 'required|numeric|exists:tb_board_group,id',
            'code' => [
                'required',
                'string',
                'min:3',
                'max:50',
                'alpha_dash',
                Rule::unique('tb_board_group', 'code')->ignore($boardGroupID, 'id')
            ],
            'name' => 'required|max:255',
            'sort' => 'required|numeric',
            'pc_header_content' => 'string|nullable',
            'pc_footer_content' => 'string|nullable',
            'mobile_header_content' => 'string|nullable',
            'mobile_footer_content' => 'string|nullable'
        ];

        $attributes = [
            'board_group_id' => 'PK',
            'code' => '주소',
            'name' => '제목',
            'sort' => '순서',
            'pc_header_content' => 'PC 상단 내용',
            'pc_footer_content' => 'PC 하단 내용',
            'mobile_header_content' => '모바일 상단 내용',
            'mobile_footer_content' => '모바일 하단 내용'
        ];

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

        $result = $this->boardGroupModel->updater($boardGroupID, $request, $response);

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

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

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

        if($posts['chk']) {
            foreach($posts['chk'] as $boardGroupID) {
                $updateData = [
                    'code' => ($posts['code'][$boardGroupID] ?? ''),
                    'name' => ($posts['name'][$boardGroupID] ?? ''),
                    'sort' => ($posts['sort'][$boardGroupID] ?? ''),
                ];

                $rules = [
                    'code' => [
                        'required',
                        'string',
                        'min:3',
                        'max:50',
                        'alpha_dash',
                        Rule::unique('tb_board_group', 'code')->ignore($boardGroupID, 'id')
                    ],
                    'name' => 'required|max:255',
                    'sort' => 'required|numeric'
                ];

                $attributes = [
                    'code' => 'CODE',
                    'name' => '제목',
                    'sort' => '순서'
                ];

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

                $this->boardGroupModel->find($boardGroupID)->update($updateData);
            }
        }

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

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

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

            if ($chk) {
                foreach ($chk as $boardGroupID) {

                    $boardGroup = $this->boardGroupModel->findOrNew($boardGroupID);

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

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

                    $this->boardGroupModel->remove($boardGroupID);
                }
            }

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