<?php

namespace App\Controllers\Admin;

use App\Controllers\BaseController;
use App\Models\DesignatedShopModel;
use App\Models\LocalGovernmentModel;
use Config\Roles;

class DesignatedShop extends BaseController
{
    private DesignatedShopModel $shopModel;
    private LocalGovernmentModel $lgModel;
    private Roles $roles;

    public function __construct()
    {
        $this->shopModel = model(DesignatedShopModel::class);
        $this->lgModel   = model(LocalGovernmentModel::class);
        $this->roles     = config('Roles');
    }

    private function isSuperAdmin(): bool
    {
        return (int) session()->get('mb_level') === Roles::LEVEL_SUPER_ADMIN;
    }

    private function isLocalAdmin(): bool
    {
        return (int) session()->get('mb_level') === Roles::LEVEL_LOCAL_ADMIN;
    }

    /**
     * 지정판매소 목록 (효과 지자체 기준: super admin = 선택 지자체, 지자체관리자 = mb_lg_idx)
     */
    public function index()
    {
        helper('admin');
        $lgIdx = admin_effective_lg_idx();

        if ($lgIdx === null || $lgIdx <= 0) {
            return redirect()->to(site_url('admin'))
                ->with('error', '작업할 지자체가 선택되지 않았습니다. 지자체를 선택해 주세요.');
        }

        $list = $this->shopModel
            ->where('ds_lg_idx', $lgIdx)
            ->orderBy('ds_idx', 'DESC')
            ->findAll();

        // 지자체 이름 매핑용
        $lgMap = [];
        foreach ($this->lgModel->findAll() as $lg) {
            $lgMap[$lg->lg_idx] = $lg->lg_name;
        }

        return view('admin/layout', [
            'title'   => '지정판매소 관리',
            'content' => view('admin/designated_shop/index', [
                'list'  => $list,
                'lgMap' => $lgMap,
            ]),
        ]);
    }

    /**
     * 지정판매소 등록 폼 (효과 지자체 기준)
     */
    public function create()
    {
        helper('admin');
        $lgIdx = admin_effective_lg_idx();
        if ($lgIdx === null || $lgIdx <= 0) {
            return redirect()->to(site_url('admin/designated-shops'))
                ->with('error', '작업할 지자체가 선택되지 않았습니다. 지자체를 선택해 주세요.');
        }

        $currentLg = $this->lgModel->find($lgIdx);
        if ($currentLg === null) {
            return redirect()->to(site_url('admin/designated-shops'))
                ->with('error', '선택한 지자체 정보를 찾을 수 없습니다.');
        }

        return view('admin/layout', [
            'title'   => '지정판매소 등록',
            'content' => view('admin/designated_shop/create', [
                'localGovs' => [],
                'currentLg' => $currentLg,
            ]),
        ]);
    }

    /**
     * 지정판매소 등록 처리
     */
    public function store()
    {
        if (! $this->isSuperAdmin() && ! $this->isLocalAdmin()) {
            return redirect()->to(site_url('admin/designated-shops'))
                ->with('error', '지정판매소 등록은 관리자만 가능합니다.');
        }

        $rules = [
            'ds_name'      => 'required|max_length[100]',
            'ds_biz_no'    => 'required|max_length[20]',
            'ds_rep_name'  => 'required|max_length[50]',
            'ds_va_number' => 'permit_empty|max_length[50]',
            'ds_email'     => 'permit_empty|valid_email|max_length[100]',
        ];

        if (! $this->validate($rules)) {
            return redirect()->back()
                ->withInput()
                ->with('errors', $this->validator->getErrors());
        }

        helper('admin');
        $lgIdx = admin_effective_lg_idx();
        if ($lgIdx === null || $lgIdx <= 0) {
            return redirect()->back()
                ->withInput()
                ->with('error', '소속 지자체가 올바르지 않습니다.');
        }

        $lg = $this->lgModel->find($lgIdx);
        if ($lg === null || (string) $lg->lg_code === '') {
            return redirect()->back()
                ->withInput()
                ->with('error', '지자체 코드 정보를 찾을 수 없습니다.');
        }

        $dsShopNo = $this->generateNextShopNo($lgIdx, (string) $lg->lg_code);

        $data = [
            'ds_lg_idx'        => $lgIdx,
            'ds_mb_idx'        => null,
            'ds_shop_no'       => $dsShopNo,
            'ds_name'          => (string) $this->request->getPost('ds_name'),
            'ds_biz_no'        => (string) $this->request->getPost('ds_biz_no'),
            'ds_rep_name'      => (string) $this->request->getPost('ds_rep_name'),
            'ds_va_number'     => (string) $this->request->getPost('ds_va_number'),
            'ds_zip'           => (string) $this->request->getPost('ds_zip'),
            'ds_addr'          => (string) $this->request->getPost('ds_addr'),
            'ds_addr_jibun'    => (string) $this->request->getPost('ds_addr_jibun'),
            'ds_tel'           => (string) $this->request->getPost('ds_tel'),
            'ds_rep_phone'     => (string) $this->request->getPost('ds_rep_phone'),
            'ds_email'         => (string) $this->request->getPost('ds_email'),
            'ds_gugun_code'    => (string) $lg->lg_code,
            'ds_designated_at' => $this->request->getPost('ds_designated_at') ?: null,
            'ds_state'         => 1,
            'ds_regdate'       => date('Y-m-d H:i:s'),
        ];

        $this->shopModel->insert($data);

        return redirect()->to(site_url('admin/designated-shops'))
            ->with('success', '지정판매소가 등록되었습니다.');
    }

    /**
     * 지정판매소 수정 폼 (효과 지자체 소속만 허용)
     * 문서: docs/기본 개발계획/23-지정판매소_수정_삭제_기능.md
     */
    public function edit(int $id)
    {
        if (! $this->isSuperAdmin() && ! $this->isLocalAdmin()) {
            return redirect()->to(site_url('admin/designated-shops'))
                ->with('error', '권한이 없습니다.');
        }

        helper('admin');
        $lgIdx = admin_effective_lg_idx();
        if ($lgIdx === null || $lgIdx <= 0) {
            return redirect()->to(site_url('admin/designated-shops'))
                ->with('error', '작업할 지자체가 선택되지 않았습니다.');
        }

        $shop = $this->shopModel->find($id);
        if ($shop === null || (int) $shop->ds_lg_idx !== $lgIdx) {
            return redirect()->to(site_url('admin/designated-shops'))
                ->with('error', '해당 지정판매소를 찾을 수 없거나 수정할 수 없습니다.');
        }

        $currentLg = $this->lgModel->find($lgIdx);

        return view('admin/layout', [
            'title'   => '지정판매소 수정',
            'content' => view('admin/designated_shop/edit', [
                'shop'      => $shop,
                'currentLg' => $currentLg,
            ]),
        ]);
    }

    /**
     * 지정판매소 수정 처리
     */
    public function update(int $id)
    {
        if (! $this->isSuperAdmin() && ! $this->isLocalAdmin()) {
            return redirect()->to(site_url('admin/designated-shops'))
                ->with('error', '권한이 없습니다.');
        }

        helper('admin');
        $lgIdx = admin_effective_lg_idx();
        if ($lgIdx === null || $lgIdx <= 0) {
            return redirect()->to(site_url('admin/designated-shops'))
                ->with('error', '작업할 지자체가 선택되지 않았습니다.');
        }

        $shop = $this->shopModel->find($id);
        if ($shop === null || (int) $shop->ds_lg_idx !== $lgIdx) {
            return redirect()->to(site_url('admin/designated-shops'))
                ->with('error', '해당 지정판매소를 찾을 수 없거나 수정할 수 없습니다.');
        }

        $rules = [
            'ds_name'      => 'required|max_length[100]',
            'ds_biz_no'    => 'required|max_length[20]',
            'ds_rep_name'  => 'required|max_length[50]',
            'ds_va_number' => 'permit_empty|max_length[50]',
            'ds_email'     => 'permit_empty|valid_email|max_length[100]',
            'ds_state'     => 'permit_empty|in_list[1,2,3]',
        ];

        if (! $this->validate($rules)) {
            return redirect()->back()
                ->withInput()
                ->with('errors', $this->validator->getErrors());
        }

        $data = [
            'ds_name'          => (string) $this->request->getPost('ds_name'),
            'ds_biz_no'        => (string) $this->request->getPost('ds_biz_no'),
            'ds_rep_name'      => (string) $this->request->getPost('ds_rep_name'),
            'ds_va_number'     => (string) $this->request->getPost('ds_va_number'),
            'ds_zip'           => (string) $this->request->getPost('ds_zip'),
            'ds_addr'          => (string) $this->request->getPost('ds_addr'),
            'ds_addr_jibun'    => (string) $this->request->getPost('ds_addr_jibun'),
            'ds_tel'           => (string) $this->request->getPost('ds_tel'),
            'ds_rep_phone'     => (string) $this->request->getPost('ds_rep_phone'),
            'ds_email'         => (string) $this->request->getPost('ds_email'),
            'ds_designated_at' => $this->request->getPost('ds_designated_at') ?: null,
            'ds_state'         => (int) ($this->request->getPost('ds_state') ?: 1),
        ];

        $this->shopModel->update($id, $data);

        return redirect()->to(site_url('admin/designated-shops'))
            ->with('success', '지정판매소 정보가 수정되었습니다.');
    }

    /**
     * 지정판매소 삭제 (물리 삭제, 효과 지자체 소속만 허용)
     * 문서: docs/기본 개발계획/23-지정판매소_수정_삭제_기능.md
     */
    public function delete(int $id)
    {
        if (! $this->isSuperAdmin() && ! $this->isLocalAdmin()) {
            return redirect()->to(site_url('admin/designated-shops'))
                ->with('error', '권한이 없습니다.');
        }

        helper('admin');
        $lgIdx = admin_effective_lg_idx();
        if ($lgIdx === null || $lgIdx <= 0) {
            return redirect()->to(site_url('admin/designated-shops'))
                ->with('error', '작업할 지자체가 선택되지 않았습니다.');
        }

        $shop = $this->shopModel->find($id);
        if ($shop === null || (int) $shop->ds_lg_idx !== $lgIdx) {
            return redirect()->to(site_url('admin/designated-shops'))
                ->with('error', '해당 지정판매소를 찾을 수 없거나 삭제할 수 없습니다.');
        }

        $this->shopModel->delete($id);

        return redirect()->to(site_url('admin/designated-shops'))
            ->with('success', '지정판매소가 삭제되었습니다.');
    }

    /**
     * 지자체별 다음 판매소번호 생성 (lg_code + 3자리 일련번호)
     * 문서: docs/기본 개발계획/22-판매소번호_일련번호_결정.md §3
     */
    private function generateNextShopNo(int $lgIdx, string $lgCode): string
    {
        $prefixLen = strlen($lgCode);
        $existing  = $this->shopModel->where('ds_lg_idx', $lgIdx)->findAll();

        $maxSerial = 0;
        foreach ($existing as $row) {
            $no = $row->ds_shop_no;
            if (strlen($no) === $prefixLen + 3 && str_starts_with($no, $lgCode)) {
                $n = (int) substr($no, -3);
                if ($n > $maxSerial) {
                    $maxSerial = $n;
                }
            }
        }

        return $lgCode . sprintf('%03d', $maxSerial + 1);
    }
}

