<?php

namespace App\Controllers\Admin;

use App\Controllers\BaseController;
use App\Models\MemberApprovalRequestModel;
use App\Models\MemberModel;
use Config\Roles;

class User extends BaseController
{
    private MemberModel $memberModel;
    private MemberApprovalRequestModel $approvalModel;
    private Roles $roles;

    public function __construct()
    {
        $this->memberModel = model(MemberModel::class);
        $this->approvalModel = model(MemberApprovalRequestModel::class);
        $this->roles      = config('Roles');
        helper('pii_encryption');
    }

    /**
     * 회원 목록
     */
    public function index(): string
    {
        $list = $this->memberModel->orderBy('mb_idx', 'DESC')->findAll();
        $approvalMap = [];
        try {
            $memberIds = array_map(static fn ($row) => (int) $row->mb_idx, $list);
            if (! empty($memberIds)) {
                $approvalRows = $this->approvalModel
                    ->whereIn('mb_idx', $memberIds)
                    ->orderBy('mar_idx', 'DESC')
                    ->findAll();
                foreach ($approvalRows as $approvalRow) {
                    $mbIdx = (int) $approvalRow->mb_idx;
                    if (! isset($approvalMap[$mbIdx])) {
                        $approvalMap[$mbIdx] = (string) $approvalRow->mar_status;
                    }
                }
            }
        } catch (\Throwable $e) {
            // 승인요청 테이블 미생성 등 예외 시 기존 상태 표시로 폴백
        }

        foreach ($list as $row) {
            $row->mb_email = pii_decrypt($row->mb_email ?? '');
            $row->mb_phone = pii_decrypt($row->mb_phone ?? '');
        }
        return view('admin/layout', [
            'title'   => '회원 관리',
            'content' => view('admin/user/index', [
                'list'        => $list,
                'roles'       => $this->roles,
                'approvalMap' => $approvalMap,
            ]),
        ]);
    }

    /**
     * 회원 등록 폼
     */
    public function create(): string
    {
        return view('admin/layout', [
            'title'   => '회원 등록',
            'content' => view('admin/user/create', [
                'roles'            => $this->roles,
                'assignableLevels' => $this->getAssignableLevels(),
            ]),
        ]);
    }

    /**
     * 회원 등록 처리
     */
    public function store()
    {
        $rules = [
            'mb_id'     => 'required|min_length[2]|max_length[50]|is_unique[member.mb_id]',
            'mb_passwd' => 'required|min_length[4]|max_length[255]',
            'mb_name'   => 'required|max_length[50]',
            'mb_email'  => 'permit_empty|valid_email|max_length[100]',
            'mb_phone'  => 'permit_empty|max_length[20]',
            'mb_level'  => 'required',
        ];
        if (! $this->validate($rules)) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }
        $allowedLevels = array_keys($this->getAssignableLevels());
        $requestedLevel = (int) $this->request->getPost('mb_level');
        if (! in_array($requestedLevel, $allowedLevels, true)) {
            return redirect()->back()->withInput()->with('error', '현재 권한으로는 해당 역할을 등록할 수 없습니다.');
        }
        $data = [
            'mb_id'       => $this->request->getPost('mb_id'),
            'mb_passwd'   => password_hash((string) $this->request->getPost('mb_passwd'), PASSWORD_DEFAULT),
            'mb_name'     => $this->request->getPost('mb_name'),
            'mb_email'    => pii_encrypt($this->request->getPost('mb_email')),
            'mb_phone'    => pii_encrypt($this->request->getPost('mb_phone')),
            'mb_level'    => $requestedLevel,
            'mb_state'    => 1,
            'mb_regdate'  => date('Y-m-d H:i:s'),
            'mb_latestdate' => null,
        ];
        $this->memberModel->insert($data);
        return redirect()->to(site_url('admin/users'))->with('success', '회원이 등록되었습니다.');
    }

    /**
     * 회원 수정 폼
     */
    public function edit(int $id): string
    {
        $member = $this->memberModel->find($id);
        if (! $member) {
            return redirect()->to(site_url('admin/users'))->with('error', '회원을 찾을 수 없습니다.');
        }
        $member->mb_email = pii_decrypt($member->mb_email ?? '');
        $member->mb_phone = pii_decrypt($member->mb_phone ?? '');
        return view('admin/layout', [
            'title'   => '회원 수정',
            'content' => view('admin/user/edit', [
                'member'           => $member,
                'roles'            => $this->roles,
                'assignableLevels' => $this->getAssignableLevels(),
            ]),
        ]);
    }

    /**
     * 회원 수정 처리
     */
    public function update(int $id)
    {
        $member = $this->memberModel->find($id);
        if (! $member) {
            return redirect()->to(site_url('admin/users'))->with('error', '회원을 찾을 수 없습니다.');
        }
        $rules = [
            'mb_id'    => "required|min_length[2]|max_length[50]|is_unique[member.mb_id,mb_idx,{$id}]",
            'mb_name'  => 'required|max_length[50]',
            'mb_email' => 'permit_empty|valid_email|max_length[100]',
            'mb_phone' => 'permit_empty|max_length[20]',
            'mb_level' => 'required',
            'mb_state' => 'required|in_list[0,1,2]',
        ];
        $passwd = $this->request->getPost('mb_passwd');
        if ($passwd !== '') {
            $rules['mb_passwd'] = 'min_length[4]|max_length[255]';
        }
        if (! $this->validate($rules)) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }
        $allowedLevels = array_keys($this->getAssignableLevels());
        $requestedLevel = (int) $this->request->getPost('mb_level');
        if (! in_array($requestedLevel, $allowedLevels, true)) {
            return redirect()->back()->withInput()->with('error', '현재 권한으로는 해당 역할로 수정할 수 없습니다.');
        }
        $data = [
            'mb_id'    => $this->request->getPost('mb_id'),
            'mb_name'  => $this->request->getPost('mb_name'),
            'mb_email' => pii_encrypt($this->request->getPost('mb_email')),
            'mb_phone' => pii_encrypt($this->request->getPost('mb_phone')),
            'mb_level' => $requestedLevel,
            'mb_state' => (int) $this->request->getPost('mb_state'),
        ];
        if ($passwd !== '') {
            $data['mb_passwd'] = password_hash($passwd, PASSWORD_DEFAULT);
        }
        $this->memberModel->update($id, $data);
        return redirect()->to(site_url('admin/users'))->with('success', '회원 정보가 수정되었습니다.');
    }

    /**
     * 현재 로그인한 관리자가 부여 가능한 역할 목록.
     * super admin만 super admin(4) 부여 가능, 그 외는 1~3만 허용.
     *
     * @return array<int,string>
     */
    private function getAssignableLevels(): array
    {
        $levelNames = $this->roles->levelNames;
        $myLevel = (int) session()->get('mb_level');
        if ($myLevel === Roles::LEVEL_SUPER_ADMIN) {
            return $levelNames;
        }
        unset($levelNames[Roles::LEVEL_SUPER_ADMIN]);
        return $levelNames;
    }

    /**
     * 회원 삭제(탈퇴 처리: mb_state=0, mb_leavedate 기록)
     */
    public function delete(int $id)
    {
        $member = $this->memberModel->find($id);
        if (! $member) {
            return redirect()->to(site_url('admin/users'))->with('error', '회원을 찾을 수 없습니다.');
        }
        $this->memberModel->update($id, [
            'mb_state'     => 0,
            'mb_leavedate' => date('Y-m-d H:i:s'),
        ]);
        return redirect()->to(site_url('admin/users'))->with('success', '회원이 탈퇴 처리되었습니다.');
    }
}
