<?php

namespace App\Http\Controllers\Admin;

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

class ContractorController extends Controller
{
    /**
     * 一覧表示（GET/POST）
     */
    public function list(Request $request)
    {
        // ベースクエリを構築
        $q = DB::table('regular_contract as rc')
            ->leftJoin('user as u','rc.user_id','=','u.user_id')
            ->select([
                'rc.contract_id',
                'rc.contract_qr_id',
                'rc.user_id',
                'rc.user_categoryid',
                'rc.park_id',
                'rc.contract_created_at',
                'rc.contract_periods',
                'rc.contract_periode',
                'rc.tag_qr_flag',
                'rc.contract_flag',
                'rc.contract_cancel_flag',
                'rc.contract_payment_day',
                'rc.contract_money',
                'rc.billing_amount',
                'rc.contract_permission',
                'rc.contract_manual',
                'rc.contract_notice',
                'rc.update_flag',
                'p.park_name',
                'u.user_name',
                'u.user_phonetic',
                'u.user_mobile',
                'u.user_seq',
                'u.user_homephone',
                'u.user_primemail',
                'u.user_gender',
                'u.user_birthdate',
                'u.user_regident_zip',
                'u.user_regident_pre',
                'u.user_regident_city',
                'u.user_regident_add',
                'u.user_relate_zip',
                'u.user_relate_pre',
                'u.user_relate_city',
                'u.user_relate_add',
                'u.user_graduate',
                'u.user_workplace',
                'u.user_school',
                'u.user_remarks',
                'u.user_tag_serial_64',
                'u.user_reduction',
                DB::raw('rc.user_securitynum as crime_prevention'),
                DB::raw('rc.contract_seal_issue as seal_issue_count'),
                DB::raw("CASE rc.enable_months 
                         WHEN 1 THEN '月極(1ヶ月)'
                         WHEN 3 THEN '3ヶ月'
                         WHEN 6 THEN '6ヶ月'
                         WHEN 12 THEN '年' 
                         ELSE CONCAT(rc.enable_months, 'ヶ月') END as ticket_type"),
                DB::raw('ps.psection_subject as vehicle_type'),
                // 利用者分類のラベル（usertype テーブルの subject を取得）
                DB::raw('ut.usertype_subject1 as user_category1'),
                DB::raw('ut.usertype_subject2 as user_category2'),
                DB::raw('ut.usertype_subject3 as user_category3'),
            ])
            ->leftJoin('park as p', 'rc.park_id', '=', 'p.park_id')
            ->leftJoin('psection as ps', 'rc.psection_id', '=', 'ps.psection_id')
            ->leftJoin('usertype as ut', 'u.user_categoryid', '=', 'ut.user_categoryid');

        // ===== 絞り込み条件 =====

        // 駐輪場で絞る（完全一致）
        if ($request->filled('park_id')) {
            $q->where('rc.park_id', $request->park_id);
        }

        // 利用者IDで絞る（完全一致）
        if ($request->filled('user_id')) {
            $q->where('rc.user_id', $request->user_id);
        }

        // 利用者分類で絞る（※ select の value を user_categoryid にしているため、user テーブルのカラムで比較）
        if ($request->filled('user_category1')) {
            $q->where('u.user_categoryid', $request->user_category1);
        }

        // タグシリアル64進で部分一致検索
        if ($request->filled('user_tag_serial_64')) {
            $val = $request->user_tag_serial_64;
            $q->where('u.user_tag_serial_64','like','%'.$val.'%');
        }

        // 有効期限で絞る（指定日以前を抽出する＝ <= を使用）
        if ($request->filled('contract_periode')) {
            $raw  = trim($request->contract_periode);
            $norm = str_replace('/', '-', $raw); // スラッシュ入力を許容
            try {
                $target = \Carbon\Carbon::parse($norm)->format('Y-m-d');
                // 指定日「以前」を含める
                $q->whereDate('rc.contract_periode', '<=', $target);
            } catch (\Exception $e) {
                // 無効な日付は無視する
            }
        }

        // フリガナで部分一致
        if ($request->filled('user_phonetic')) {
            $q->where('u.user_phonetic', 'like', '%' . $request->user_phonetic . '%');
        }

        // 携帯電話で部分一致
        if ($request->filled('user_mobile')) {
            $q->where('u.user_mobile', 'like', '%' . $request->user_mobile . '%');
        }

        // メールアドレスで部分一致
        if ($request->filled('user_primemail')) {
            $q->where('u.user_primemail', 'like', '%' . $request->user_primemail . '%');
        }

        // 勤務先で部分一致
        if ($request->filled('user_workplace')) {
            $q->where('u.user_workplace', 'like', '%' . $request->user_workplace . '%');
        }

        // 学校で部分一致
        if ($request->filled('user_school')) {
            $q->where('u.user_school', 'like', '%' . $request->user_school . '%');
        }

        // タグ・QR フラグで絞る（空文字は無視）
        if ($request->filled('tag_qr_flag') && $request->tag_qr_flag !== '') {
            $q->where('rc.tag_qr_flag', $request->tag_qr_flag);
        }

        // ===== ソート処理 =====
        // 指定があればその列でソート、なければデフォルトで契約IDの昇順
        $sort = $request->input('sort');            // null 許容
        $sortType = $request->input('sort_type','asc');

        $allowSorts = [
            'rc.contract_id',
            'rc.user_id',
            'u.user_name',
            'rc.tag_qr_flag',
            'p.park_name',
        ];
        if ($sort && in_array($sort, $allowSorts)) {
            $sortType = $sortType === 'desc' ? 'desc' : 'asc';
            $q->orderBy($sort, $sortType);
        } else {
            // デフォルトソート
            $sort = null;
            $sortType = null;
            $q->orderBy('rc.contract_id','asc');
        }

        // ページネーション（クエリ文字列を引き継ぐ）
        $rows = $q->paginate(20)->appends($request->query());

        // 駐輪場セレクト用データ取得
        $parks = DB::table('park')->select('park_id', 'park_name')->orderBy('park_name')->get();

        // 利用者分類セレクト用：実際に使用されている分類のみを取得する
        $categories = $this->buildCategoryOptions(true);

        // ビューに渡す
        return view('admin.contractor.list', compact('rows', 'sort', 'sortType', 'parks', 'categories'));
    }

    /**
     * 詳細表示
     */
    public function info($id)
    {
        // 指定契約IDの詳細を取得
        $contract = DB::table('regular_contract as rc')
            ->select([
                'rc.*',
                'p.park_name',
                'u.user_name',
                'u.user_phonetic',
                'u.user_mobile',
                'u.user_homephone',
                'u.user_primemail',
                'u.user_gender',
                'u.user_birthdate',
                'u.user_regident_city',
            ])
            ->leftJoin('park as p', 'rc.park_id', '=', 'p.park_id')
            ->leftJoin('user as u', 'rc.user_id', '=', 'u.user_id')
            ->where('rc.contract_id', $id)
            ->first();

        if (!$contract) { abort(404); }

        return view('admin.contractor.info', compact('contract'));
    }

    /**
     * 利用者分類選択肢を取得
     *
     * @param bool $onlyUsed true の場合は regular_contract に出現する分類のみ返す
     * @return array [user_categoryid => label, ...]
     */
    private function buildCategoryOptions(bool $onlyUsed = false): array
    {
        if (! $onlyUsed) {
            // 全件取得（既存の挙動）
            return DB::table('usertype')
                ->orderBy('user_categoryid', 'asc')
                ->get()
                ->mapWithKeys(function ($row) {
                    $label = collect([
                        $row->usertype_subject1 ?? '',
                        $row->usertype_subject2 ?? '',
                        $row->usertype_subject3 ?? '',
                    ])->filter(fn ($v) => $v !== '')->implode('/');

                    return [$row->user_categoryid => $label !== '' ? $label : (string) $row->user_categoryid];
                })
                ->toArray();
        }

        // 実際に使用されている分類のみ取得する（内部結合で user と regular_contract と紐付くもの）
        $rows = DB::table('usertype as ut')
            ->join('user as u', 'u.user_categoryid', '=', 'ut.user_categoryid')
            ->join('regular_contract as rc', 'rc.user_id', '=', 'u.user_id')
            ->select(
                'ut.user_categoryid',
                'ut.usertype_subject1',
                'ut.usertype_subject2',
                'ut.usertype_subject3'
            )
            ->groupBy('ut.user_categoryid', 'ut.usertype_subject1', 'ut.usertype_subject2', 'ut.usertype_subject3')
            ->orderBy('ut.user_categoryid', 'asc')
            ->get();

        // ラベルを組み立てて配列で返す
        return $rows->mapWithKeys(function ($row) {
            $label = collect([
                $row->usertype_subject1 ?? '',
                $row->usertype_subject2 ?? '',
                $row->usertype_subject3 ?? '',
            ])->filter(fn ($v) => $v !== '')->implode('/');

            return [$row->user_categoryid => $label !== '' ? $label : (string) $row->user_categoryid];
        })->toArray();
    }
}
