<?php

namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
use App\Models\City;

class CityController extends Controller
{
    public function list(Request $request)
    {
        $sort = $request->input('sort', 'city_id');
        $sortType = $request->input('sort_type', 'asc');
        $page = (int)$request->get('page', 1);

        $menuAccessService = app(\App\Services\MenuAccessService::class);

        // メニューアクセス制御: 非ソーリンユーザーは所属自治体のみ表示
        $query = City::query();
        if (!$menuAccessService->isSorin()) {
            $operator = auth()->user();
            if ($operator && isset($operator->management_id)) {
                $query->where('management_id', $operator->management_id);
            }
        }

        if ($request->filled('city_name')) {
            $query->where('city_name', 'like', '%' . $request->input('city_name') . '%');
        }

        if (!empty($sort)) {
            $query->orderBy($sort, $sortType);
        }

        $list = $query->paginate(50);

        // インデックス超過処理
        if ($list->total() > 0 && $page > $list->lastPage()) {
            return redirect()->route('city', [
                'sort' => $sort,
                'sort_type' => $sortType,
            ]);
        }

        return view('admin.cities.list', [
            'sort' => $sort,
            'sort_type' => $sortType,
            'list' => $list,
            'page' => $page,
        ]);
    }

    /** 新規画面 */
    public function add(Request $request)
    {
        $record = new City();

        return view('admin.cities.add', [
            'record' => $record,
            'errorMsg' => [],
        ]);
    }

    /** 登録 */
    public function store(Request $request)
    {
        [$rules, $messages] = $this->rulesAndMessages();
        $validator = Validator::make($request->all(), $rules, $messages);

        $record = new City();

        if ($validator->fails()) {
            
            $record->fill($request->only(['city_name', 'print_layout', 'city_remarks']));

            return view('admin.cities.add', [
                'record' => $record,
                'errorMsg' => $validator->errors()->all(),
            ]);
        }

        $maxId = DB::table('city')->max('city_id');
        $newCityId = $maxId ? $maxId + 1 : 1;

        $record->city_id = $newCityId;
        $record->fill($request->only([
            'city_name',
            'print_layout',
            'city_remarks',
        ]));

        if ($record->save()) {
            return redirect()->route('city')->with('success', __('登録に成功しました'));
        }

        return back()->withInput()->with('error', __('登録に失敗しました'));
    }

    /** 編集画面 */
    public function edit(Request $request, $id)
    {
        $record = City::find($id);
        if (!$record) {
            abort(404);
        }

        $this->authorizeCityAccess($record);

        return view('admin.cities.edit', [
            'record' => $record,
            'errorMsg' => [],
        ]);
    }

    /** 更新 */
    public function update(Request $request, $id)
    {
        $record = City::find($id);
        if (!$record) {
            abort(404);
        }

        $this->authorizeCityAccess($record);

        [$rules, $messages] = $this->rulesAndMessages();
        $validator = Validator::make($request->all(), $rules, $messages);

        if ($validator->fails()) {
            // 画面に戻る時に入力を保持
            $record->fill($request->only(['city_name', 'print_layout', 'city_remarks']));

            return view('admin.cities.edit', [
                'record' => $record,
                'errorMsg' => $validator->errors()->all(),
            ]);
        }

        $record->fill($request->only([
            'city_name',
            'print_layout',
            'city_remarks',
        ]));

        if ($record->save()) {
            return redirect()->route('city')->with('success', __('更新に成功しました'));
        }

        return back()->withInput()->with('error', __('更新に失敗しました'));
    }

    public function delete(Request $request)
    {
        $arr_pk = $request->get('pk');
        if (!$arr_pk) {
            return redirect()->route('city')->with('error', __('削除する市区を選択してください。'));
        }

        if (City::destroy($arr_pk)) {
            return redirect()->route('city')->with('success', __("削除が完了しました。"));
        }

        return redirect()->route('city')->with('error', __('削除に失敗しました。'));
    }

    private function rulesAndMessages(): array
    {
        $rules = [
            // 市区名：全角 / 必須 / 最大20文字
            'city_name' => [
                'required',
                'string',
                'max:20',
                'regex:/^[^ -~｡-ﾟ]+$/u',
            ],

            // 印字レイアウトファイル：半角英数字 / 必須 / 最大255文字
            'print_layout' => [
                'required',
                'string',
                'max:255',
                'regex:/^[A-Za-z0-9]+$/',
            ],

            // 備考：任意 / 最大255文字
            'city_remarks' => [
                'nullable',
                'string',
                'max:255',
            ],
        ];

        $messages = [
            'city_name.required' => '市区名は必須です。',
            'city_name.regex'    => '市区名は全角文字で入力してください。',
            'city_name.max'      => '市区名は20文字以内で入力してください。',

            'print_layout.required' => '印字レイアウトファイルは必須です。',
            'print_layout.regex'    => '印字レイアウトファイルは半角英数字で入力してください。',
            'print_layout.max'      => '印字レイアウトファイルは255文字以内で入力してください。',

            'city_remarks.max'      => '備考は255文字以内で入力してください。',
        ];

        return [$rules, $messages];
    }

    private function authorizeCityAccess(City $city): void
    {
        $menuAccessService = app(\App\Services\MenuAccessService::class);
        if (!$menuAccessService->canAccessCity($city->city_id)) {
            abort(403, 'この自治体へのアクセス権限がありません。');
        }
    }

    /**
     * 自治体ダッシュボード（そのまま残すなら、別途 route 追加が必要）
     */
    public function dashboard(Request $request, $city_id)
    {
        $city = City::find($city_id);
        if (!$city) {
            return redirect()->route('city')->with('error', '指定された自治体が見つかりません。');
        }

        $parks = \App\Models\Park::where('city_id', $city_id)->get();
        $parkIds = $parks->pluck('park_id')->toArray();

        $contractsCount = 0;
        $usersCount = 0;
        $waitingCount = 0;

        if (!empty($parkIds)) {
            $contractsCount = \App\Models\RegularContract::whereIn('park_id', $parkIds)->count();

            $userIds = \App\Models\RegularContract::whereIn('park_id', $parkIds)
                ->distinct()
                ->pluck('user_id')
                ->toArray();
            $usersCount = count(array_filter($userIds));

            $waitingCount = DB::table('reserve')
                ->whereIn('park_id', $parkIds)
                ->where('valid_flag', 1)
                ->whereNotNull('reserve_order')
                ->where('reserve_order', '>', 0)
                ->count();
        }

        $stats = [
            'parks_count' => $parks->count(),
            'contracts_count' => $contractsCount,
            'users_count' => $usersCount,
            'waiting_count' => $waitingCount,
        ];

        return view('admin.CityMaster.dashboard', compact('city', 'parks', 'stats'));
    }
}
