<?php

namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;

class RegularContractController
{
    /**
     * 定期契約一覧
     * - ベース表: regular_contract（rc）
     * - 付加情報: user（u）, usertype（t）, park（p）
     * - 画面変数: $list, $sort, $sort_type（既存に合わせる）
     */
    public function list(Request $request)
    {
        // ===== ソート（既定: contract_id DESC）=====
        $sort = $request->input('sort', 'contract_id');
        $sortType = strtolower($request->input('sort_type', 'desc')) === 'asc' ? 'asc' : 'desc';

        // ===== 絞り込み（テキスト系）=====
        // フォームの name 属性と完全一致させる＆既定値は空文字にして Blade が未定義にならないようにする
        $contract_qr_id = trim((string) $request->input('contract_qr_id', ''));
        $user_id = trim((string) $request->input('user_id', ''));
        $park_id = trim((string) $request->input('park_id', ''));
        $user_phonetic = trim((string) $request->input('user_phonetic', '')); // フリガナ
        $phone = trim((string) $request->input('phone', ''));         // 電話（携帯/自宅）
        $email = trim((string) $request->input('email', ''));         // メール
        $usertype_name_kw = trim((string) $request->input('usertype_name', '')); // 利用者分類名
        $park_name_kw = trim((string) $request->input('park_name', ''));     // 駐輪場名

        // ===== 絞り込み（日付範囲）=====
        $reserve_from = $request->input('reserve_date_from', '');
        $reserve_to = $request->input('reserve_date_to', '');
        $created_from = $request->input('contract_created_from', '');
        $created_to = $request->input('contract_created_to', '');
        $updated_from = $request->input('contract_updated_from', '');
        $updated_to = $request->input('contract_updated_to', '');
        $canceled_from = $request->input('contract_canceled_from', '');
        $canceled_to = $request->input('contract_canceled_to', '');

        // ===== 列挙（全て/0/1）=====
        $contract_flag = $request->input('contract_flag', '');
        $contract_permission = $request->input('contract_permission', '');
        $tag_qr_flag = $request->input('tag_qr_flag', '');
        $update_flag = $request->input('update_flag', '');
        $contract_cancel_flag = $request->input('contract_cancel_flag', '');

        // ===== クエリ（結合込み）=====
        $q = DB::table('regular_contract as rc')
            ->leftJoin('user as u', 'u.user_id', '=', 'rc.user_id')
            ->leftJoin('usertype as t', 't.user_categoryid', '=', 'rc.user_categoryid')
            ->leftJoin('park as p', 'p.park_id', '=', 'rc.park_id')
            ->select([
                // rc
                'rc.contract_id',
                'rc.contract_qr_id',
                'rc.user_id',
                'rc.user_categoryid',
                'rc.reserve_id',
                'rc.park_id',
                'rc.price_parkplaceid',
                'rc.user_securitynum',
                'rc.reserve_date',
                'rc.contract_reserve',
                'rc.contract_created_at',
                'rc.contract_updated_at',
                'rc.contract_cancelday',
                'rc.contract_flag',
                'rc.contract_permission',
                'rc.contract_cancel_flag',
                'rc.tag_qr_flag',
                'rc.update_flag',
                'rc.park_position',
                'rc.ope_id',
                // user
                'u.user_name',
                'u.user_phonetic',
                'u.user_mobile',
                'u.user_homephone',
                'u.user_primemail',
                // usertype & park
                DB::raw('t.print_name as usertype_name'),
                DB::raw('p.park_name as park_name'),
            ]);

        // ===== LIKE / キーワード =====
        if ($contract_qr_id !== '') {
            $q->where('rc.contract_qr_id', 'like', "%{$contract_qr_id}%");
        }
        if ($user_id !== '') {
            $q->where('rc.user_id', 'like', "%{$user_id}%");
        }
        if ($park_id !== '') {
            $q->where('rc.park_id', 'like', "%{$park_id}%");
        }
        if ($user_phonetic !== '') {
            $q->where('u.user_phonetic', 'like', "%{$user_phonetic}%");
        }
        if ($email !== '') {
            $q->where('u.user_primemail', 'like', "%{$email}%");
        }
        if ($usertype_name_kw !== '') {
            $q->where('t.print_name', 'like', "%{$usertype_name_kw}%");
        }
        if ($park_name_kw !== '') {
            $q->where('p.park_name', 'like', "%{$park_name_kw}%");
        }
        if ($phone !== '') {
            $q->where(function ($w) use ($phone) {
                $w->where('u.user_mobile', 'like', "%{$phone}%")
                    ->orWhere('u.user_homephone', 'like', "%{$phone}%");
            });
        }

        // ===== 日付範囲 =====
        if ($reserve_from) {
            $q->whereDate('rc.reserve_date', '>=', $reserve_from);
        }
        if ($reserve_to) {
            $q->whereDate('rc.reserve_date', '<=', $reserve_to);
        }
        if ($created_from) {
            $q->whereDate('rc.contract_created_at', '>=', $created_from);
        }
        if ($created_to) {
            $q->whereDate('rc.contract_created_at', '<=', $created_to);
        }
        if ($updated_from) {
            $q->whereDate('rc.contract_updated_at', '>=', $updated_from);
        }
        if ($updated_to) {
            $q->whereDate('rc.contract_updated_at', '<=', $updated_to);
        }
        if ($canceled_from) {
            $q->whereDate('rc.contract_cancelday', '>=', $canceled_from);
        }
        if ($canceled_to) {
            $q->whereDate('rc.contract_cancelday', '<=', $canceled_to);
        }

        // ===== 列挙フィルタ =====
        if ($contract_flag !== '') {
            $q->where('rc.contract_flag', (int) $contract_flag);
        }
        if ($contract_permission !== '') {
            $q->where('rc.contract_permission', (int) $contract_permission);
        }
        if ($tag_qr_flag !== '') {
            $q->where('rc.tag_qr_flag', (int) $tag_qr_flag);
        }
        if ($update_flag !== '') {
            $q->where('rc.update_flag', (int) $update_flag);
        }
        if ($contract_cancel_flag !== '') {
            $q->where('rc.contract_cancel_flag', (int) $contract_cancel_flag);
        }

        // ===== ソート（仮想列は結合側にマッピング）=====
        $sortable = [
            'contract_id',
            'contract_qr_id',
            'user_id',
            'user_categoryid',
            'reserve_id',
            'park_id',
            'price_parkplaceid',
            'user_securitynum',
            'reserve_date',
            'contract_reserve',
            'contract_created_at',
            'contract_updated_at',
            'contract_cancelday',
            'contract_flag',
            'contract_permission',
            'contract_cancel_flag',
            'tag_qr_flag',
            'update_flag',
            'park_position',
            'ope_id',
            // 結合先の見出し列
            'user_name',
            'user_phonetic',
            'user_mobile',
            'user_homephone',
            'user_primemail',
            'usertype_name',
            'park_name',
        ];
        if (!in_array($sort, $sortable, true)) {
            $sort = 'contract_id';
        }
        $sortMap = [
            'user_name' => 'u.user_name',
            'user_phonetic' => 'u.user_phonetic',
            'user_mobile' => 'u.user_mobile',
            'user_homephone' => 'u.user_homephone',
            'user_primemail' => 'u.user_primemail',
            'usertype_name' => 't.print_name',
            'park_name' => 'p.park_name',
        ];
        $sortColumn = $sortMap[$sort] ?? ('rc.' . $sort);

        $list = $q->orderBy($sortColumn, $sortType)->paginate(50);

        // ===== 画面へ（Blade 側が参照するすべての変数を渡す）=====
        return view('admin.regularcontracts.list', [
            'list' => $list,
            'sort' => $sort,
            'sort_type' => $sortType,

            // 入力保持（テキスト）
            'contract_qr_id' => $contract_qr_id,
            'user_id' => $user_id,
            'park_id' => $park_id,
            'user_phonetic' => $user_phonetic,
            'phone' => $phone,
            'email' => $email,
            'usertype_name' => $usertype_name_kw,
            'park_name' => $park_name_kw,

            // 入力保持（日付）
            'reserve_date_from' => $reserve_from,
            'reserve_date_to' => $reserve_to,
            'contract_created_from' => $created_from,
            'contract_created_to' => $created_to,
            'contract_updated_from' => $updated_from,
            'contract_updated_to' => $updated_to,
            'contract_canceled_from' => $canceled_from,
            'contract_canceled_to' => $canceled_to,

            // 入力保持（列挙）
            'contract_flag' => $contract_flag,
            'contract_permission' => $contract_permission,
            'tag_qr_flag' => $tag_qr_flag,
            'update_flag' => $update_flag,
            'contract_cancel_flag' => $contract_cancel_flag,
        ]);
    }

    /**
     * 定期契約編集（GET: 画面表示 / POST: 更新実行）
     * - 主キー: contract_id
     */
    public function edit(Request $request, $id)
    {
        $id = (int) $id;

        if ($request->isMethod('get')) {
            $row = DB::table('regular_contract')->where('contract_id', $id)->first();
            if (!$row) {
                abort(404);
            }
            return view('admin.regularcontracts.edit', [
                'row' => $row,
                'contract_id'  => $id,
            ]);
        }

        $v = Validator::make($request->all(), [
            'user_id' => ['required', 'integer'],
            'park_id' => ['required', 'integer'],
            // 任意項目
            'contract_qr_id' => ['nullable', 'string', 'max:255'],
            'user_categoryid' => ['nullable', 'integer'],
            'reserve_id' => ['nullable', 'integer'],
            'price_parkplaceid' => ['nullable', 'integer'],
            'user_securitynum' => ['nullable', 'string', 'max:255'],
            'reserve_date' => ['nullable', 'date'],
            'contract_reserve' => ['nullable', 'string', 'max:255'],
            'contract_created_at' => ['nullable', 'date'],
            'contract_updated_at' => ['nullable', 'date'],
            'contract_cancelday' => ['nullable', 'date'],
            'contract_flag' => ['nullable', 'integer'],
            'contract_permission' => ['nullable', 'integer'],
            'contract_cancel_flag' => ['nullable', 'integer'],
            'tag_qr_flag' => ['nullable', 'integer'],
            'park_position' => ['nullable', 'string', 'max:255'],
            'ope_id' => ['nullable', 'integer'],
        ]);

        if ($v->fails()) {
            return back()->withErrors($v)->withInput();
        }

        $data = [
            'contract_qr_id' => $request->input('contract_qr_id'),
            'user_id' => (int) $request->input('user_id'),
            'user_categoryid' => $request->input('user_categoryid'),
            'reserve_id' => $request->input('reserve_id'),
            'park_id' => (int) $request->input('park_id'),
            'price_parkplaceid' => $request->input('price_parkplaceid'),
            'user_securitynum' => $request->input('user_securitynum'),
            'reserve_date' => $request->input('reserve_date'),
            'contract_reserve' => $request->input('contract_reserve'),
            'contract_created_at' => $request->input('contract_created_at'),
            'contract_updated_at' => $request->input('contract_updated_at'),
            'contract_cancelday' => $request->input('contract_cancelday'),
            'contract_flag' => $request->input('contract_flag'),
            'contract_permission' => $request->input('contract_permission'),
            'contract_cancel_flag' => $request->input('contract_cancel_flag'),
            'tag_qr_flag' => $request->input('tag_qr_flag'),
            'park_position' => $request->input('park_position'),
            'ope_id' => $request->input('ope_id'),
            'updated_at' => now(),
        ];

        DB::table('regular_contract')->where('contract_id', $id)->update($data);

        return redirect()->route('regularcontracts')->with('success', '定期契約を更新しました。');
    }

    /**
     * 定期契約削除
     * - 物理削除（必要なら cancel フラグ運用に切替）
     */
    public function delete(Request $request)
    {
        $id = (int) $request->input('id');
        DB::table('regular_contract')->where('contract_id', $id)->delete();

        // 例：論理削除運用にする場合（必要なら運用側で切替）
        // DB::table('regular_contract')->where('contract_id', $id)->update([
        //     'contract_cancel_flag' => 1,
        //     'contract_cancelday'   => now(),
        //     'updated_at'           => now(),
        // ]);

        return redirect()->route('regularcontracts')->with('success', '定期契約を削除しました。');
    }

    /**
     * 定期契約インポート（仮実装）
     */
    public function import(Request $request)
    {
        if ($request->isMethod('get')) {
            // GET で来たら一覧へ
            return redirect()->route('regularcontracts');
        }

        // ファイル必須 & 形式チェック
        $request->validate([
            'file' => ['required', 'file', 'mimetypes:text/plain,text/csv,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
        ], [], [
            'file' => 'インポートファイル',
        ]);

        $file = $request->file('file');

        // TODO: ここで実際のインポート処理（CSV/XLSXの解析とレコード登録）を書く
        // 例：Storage::putFile('imports', $file); で一旦保存してバッチに回す etc.

        return redirect()->route('regularcontracts')->with('success', 'インポートを受け付けました。');
    }



    /**
     * 定期契約エクスポート（仮実装）
     * - 現時点では何もしません。ルーティング確認用のプレーンテキストを返します。
     * - 後で CSV / Excel 出力処理に置き換えてください。
     */

    public function export(Request $request)
    {
        // ── 出力タイプ（通常 / SMBC / 役所） ──────────────────────────────
        $type = $request->query('type'); // null | smbc | city

        // ── 出力ファイル名 ───────────────────────────────────────────────
        $downloadName = '定期契約マスタ.csv';
        if ($type === 'smbc')
            $downloadName = '定期契約マスタ_SMBC.csv';
        if ($type === 'city')
            $downloadName = '定期契約マスタ_役所提出用.csv';

        // ── 生成先（storage/app/tmp 配下の一時ファイル） ─────────────────
        $tmpDir = storage_path('app/tmp');
        if (!is_dir($tmpDir)) {
            @mkdir($tmpDir, 0755, true);
        }
        $tmpPath = $tmpDir . '/' . uniqid('regularcontracts_', true) . '.csv';

        // ── CSV を作成（Excel を考慮し UTF-8 BOM を付与） ───────────────
        $fp = fopen($tmpPath, 'w+');
        if ($fp === false) {
            abort(500, 'CSV一時ファイルを作成できませんでした。');
        }
        // Excel 対策：BOM
        fwrite($fp, "\xEF\xBB\xBF");

        // ヘッダー行（必要に応じて列を増減）
        fputcsv($fp, ['定期契約ID', '利用者ID', '駐輪場ID', '契約日時']);

        // ── データ取得（大量件数に備え chunk で分割取得） ────────────────
        // ※ list() と同等の JOIN/SELECT を最低限に簡略化
        DB::table('regular_contract as rc')
            ->leftJoin('user as u', 'u.user_id', '=', 'rc.user_id')
            ->orderBy('rc.contract_id', 'asc')
            ->select([
                'rc.contract_qr_id',
                'rc.user_id',
                'rc.park_id',
                'rc.contract_created_at',
            ])
            ->chunk(1000, function ($rows) use ($fp) {
                foreach ($rows as $r) {
                    fputcsv($fp, [
                        $r->contract_qr_id,
                        $r->user_id,
                        $r->park_id,
                        $r->contract_created_at,
                    ]);
                }
            });

        fclose($fp);

        // ── ダウンロードレスポンス（送信後に一時ファイル削除） ────────────
        return response()->download(
            $tmpPath,
            $downloadName,
            [
                'Content-Type' => 'text/csv; charset=UTF-8',
                'Content-Disposition' => 'attachment; filename="' . $downloadName . '"',
                'Pragma' => 'no-cache',
                'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
                'Expires' => '0',
            ]
        )->deleteFileAfterSend(true);
    }




    // 追加：新規登録（GET: 画面表示 / POST: 登録実行）
    public function add(Request $request)
    {
        // 画面表示
        if ($request->isMethod('get')) {
            return view('admin.regularcontracts.add');
        }

        // ========= バリデーション =========
        // ※ 必須最小限。その他は任意（nullable）
        $v = Validator::make(
            $request->all(),
            [
                'user_id' => ['required', 'integer'],
                'park_id' => ['required', 'integer'],
                'contract_qr_id' => ['nullable', 'string', 'max:255'],
                'user_categoryid' => ['nullable', 'integer'],
                'reserve_id' => ['nullable', 'integer'],
                'price_parkplaceid' => ['nullable', 'integer'],
                'reserve_date' => ['nullable', 'date'],
                'contract_created_at' => ['nullable', 'date'],
                'contract_cancelday' => ['nullable', 'date'],
                'contract_permission' => ['nullable', 'integer'],
                'contract_cancel_flag' => ['nullable', 'integer'],
                'tag_qr_flag' => ['nullable', 'integer'],
                'update_flag' => ['nullable', 'integer'],
                'park_position' => ['nullable', 'string', 'max:255'],
                'ope_id' => ['nullable', 'integer'],
                // 画面の「定期有効月数」は DB の contract_valid_months に保存する
                'enable_months' => ['nullable', 'integer', 'min:0'],
            ],
            [],
            [
                'user_id' => '利用者ID',
                'park_id' => '駐輪場ID',
                'contract_qr_id' => '定期契約QRID',
                'user_categoryid' => '利用者分類ID',
                'reserve_id' => '定期予約ID',
                'price_parkplaceid' => '駐輪場所ID',
                'reserve_date' => '予約日時',
                'contract_created_at' => '契約日時',
                'contract_cancelday' => '解約日時',
                'contract_permission' => 'シール発行許可',
                'contract_cancel_flag' => '解約フラグ',
                'tag_qr_flag' => 'タグ・QR',
                'update_flag' => '（更新元）契約更新済フラグ',
                'park_position' => '駐輪位置番号',
                'ope_id' => 'オペレータID',
                'enable_months' => '定期有効月数',
            ]
        );

        if ($v->fails()) {
            return back()->withErrors($v)->withInput();
        }

        // ========= 登録データ作成 =========
        // ここでは「regular_contract」テーブルに確実にある列を中心に保存します。
        // 追加したい列があれば、同様にキーを増やして下さい。
        $data = [
            'contract_qr_id' => $request->input('contract_qr_id'),
            'user_id' => (int) $request->input('user_id'),
            'user_categoryid' => $request->input('user_categoryid'),
            'reserve_id' => $request->input('reserve_id'),
            'park_id' => (int) $request->input('park_id'),
            'price_parkplaceid' => $request->input('price_parkplaceid'),
            'reserve_date' => $request->input('reserve_date'),
            'contract_created_at' => $request->input('contract_created_at') ?: now(), // 未指定なら現在時刻
            'contract_cancelday' => $request->input('contract_cancelday'),
            'contract_permission' => $request->input('contract_permission'),
            'contract_cancel_flag' => $request->input('contract_cancel_flag'),
            'tag_qr_flag' => $request->input('tag_qr_flag'),
            'update_flag' => $request->input('update_flag'),
            'park_position' => $request->input('park_position'),
            'ope_id' => $request->input('ope_id'),
            // 画面の enable_months → DB の contract_valid_months
            'contract_valid_months' => $request->input('enable_months'),
            'created_at' => now(),
            'updated_at' => now(),
        ];

        DB::table('regular_contract')->insert($data);

        return redirect()
            ->route('regularcontracts')
            ->with('success', '定期契約を登録しました。');
    }



}
