<?php

namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Illuminate\Support\Facades\Hash;

class UsersController
{
    /**
     * 利用者分類選択肢を取得
     */
    private function buildCategoryOptions(): array
    {
        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();
    }

    /**
     * 利用者分類１（一覧絞り込み用）
     */
    private function buildCategory1Options()
    {
        return DB::table('regular_contract')
            ->join('usertype', 'regular_contract.user_categoryid', '=', 'usertype.user_categoryid')
            ->whereNotNull('usertype.usertype_subject1')
            ->distinct()
            ->orderBy('usertype.usertype_subject1')
            ->pluck('usertype.usertype_subject1');
    }

    /**
     * 利用者分類２（一覧絞り込み用）
     */
    private function buildCategory2Options()
    {
        return DB::table('regular_contract')
            ->join('usertype', 'regular_contract.user_categoryid', '=', 'usertype.user_categoryid')
            ->whereNotNull('usertype.usertype_subject2')
            ->distinct()
            ->orderBy('usertype.usertype_subject2')
            ->pluck('usertype.usertype_subject2');
    }

    /**
     * 利用者分類３（一覧絞り込み用）
     */
    private function buildCategory3Options()
    {
        return DB::table('regular_contract')
            ->join('usertype', 'regular_contract.user_categoryid', '=', 'usertype.user_categoryid')
            ->whereNotNull('usertype.usertype_subject3')
            ->distinct()
            ->orderBy('usertype.usertype_subject3')
            ->pluck('usertype.usertype_subject3');
    }

    /**
     * 利用者一覧
     * - テーブル名: user
     * - 主キー: user_seq（AUTO_INCREMENT）:contentReference[oaicite:3]{index=3}
     * - よく使う表示項目のみ選択（必要に応じて拡張）
     */
    // 先确保：use App\Http\Controllers\Controller; を追加し、必要なら extends Controller にする
// use Symfony\Component\HttpFoundation\StreamedResponse; は既にOK

    /**
     * 一覧（絞り込み + ページング）
     */
    public function list(Request $request)
    {
        // ▼ 並び順（ホワイトリスト）
        $sortable = [
            'user_seq',
            'user_id',
            'member_id',
            'contract_number',
            'user_tag_serial',
            'user_tag_serial_64',
            'qr_code',
            'tag_qr_flag',
            'user_aid',
            'user_place_qrid',
            'user_categoryid',
            'user_name',
            'user_birthdate',
            'user_age',
            'user_mobile',
            'user_homephone',
            'user_primemail',
            'user_submail',
            'user_school',
        ];
        $sort = $request->input('sort', 'user_seq');
        $dirParam = strtolower((string) $request->input('dir', $request->input('sort_type', 'asc')));
        $sortType = $dirParam === 'asc' ? 'asc' : 'desc';
        if (!in_array($sort, $sortable, true)) {
            $sort = 'user_seq';
        }

        // ▼ 絞り込み値（'' のときだけ無視。'0' は有効値として扱う）
        $user_id = trim((string) $request->input('user_id', ''));
        $member_id = trim((string) $request->input('member_id', ''));
        $user_tag_serial = trim((string) $request->input('user_tag_serial', ''));
        $user_phonetic = trim((string) $request->input('user_phonetic', ''));
        $phone = trim((string) $request->input('phone', ''));   // 携帯/自宅の両方対象
        $crime = trim((string) $request->input('crime', ''));   // 防犯登録番号（暫定: qr_code）
        $email = trim((string) $request->input('email', ''));
        $user_category1 = trim((string) $request->input('user_category1', ''));
        $user_category2 = trim((string) $request->input('user_category2', ''));
        $user_category3 = trim((string) $request->input('user_category3', ''));
        $tag_qr_flag = (string) $request->input('tag_qr_flag', '');   // 0=タグ / 1=QR
        $quit_flag = (string) $request->input('quit_flag', '');     // 0=いいえ / 1=はい
        $quit_from = (string) $request->input('quit_from', '');     // YYYY-MM-DD
        $quit_to = (string) $request->input('quit_to', '');       // YYYY-MM-DD

        // ▼ ベースクエリ（一覧で使う列が多いので一旦 * を許容）
        $query = DB::table('user')
            ->leftJoin('usertype', 'user.user_categoryid', '=', 'usertype.user_categoryid')
            ->select(
                'user.*',
                'usertype.usertype_subject1',
                'usertype.usertype_subject2',
                'usertype.usertype_subject3'
            );

        // ▼ テキスト系
        if ($user_id !== '')
            $query->where('user.user_id', 'like', "%{$user_id}%");
        if ($member_id !== '')
            $query->where('user.member_id', 'like', "%{$member_id}%");
        if ($user_tag_serial !== '')
            $query->where('user.user_tag_serial', 'like', "%{$user_tag_serial}%");
        if ($user_phonetic !== '')
            $query->where('user.user_phonetic', 'like', "%{$user_phonetic}%");
        if ($phone !== '') {
            $query->where(function ($w) use ($phone) {
                $w->where('user.user_mobile', 'like', "%{$phone}%")
                    ->orWhere('user.user_homephone', 'like', "%{$phone}%");
            });
        }
        if ($crime !== '') {
            // ※ dump に防犯登録番号の明確なカラムが無いため暫定的に qr_code を対象
            $query->where('user.qr_code', 'like', "%{$crime}%");
        }
        if ($email !== '')
            $query->where('user.user_primemail', 'like', "%{$email}%");

        // ▼ セレクト/ラジオ（'' 以外なら適用。'0' も通す）
        if ($user_category1 !== '') {
            $query->where('usertype.usertype_subject1', $user_category1);
        }

        if ($user_category2 !== '') {
            $query->where('usertype.usertype_subject2', $user_category2);
        }

        if ($user_category3 !== '') {
            $query->where('usertype.usertype_subject3', $user_category3);
        }

        if ($tag_qr_flag !== '')
            $query->where('user.tag_qr_flag', (int) $tag_qr_flag);
        if ($quit_flag !== '')
            $query->where('user.user_quit_flag', (int) $quit_flag);

        // ▼ 日付範囲（退会日）
        if ($quit_from !== '')
            $query->where('user.user_quitday', '>=', $quit_from);
        if ($quit_to !== '')
            $query->where('user.user_quitday', '<=', $quit_to);

        // ▼ 並び & ページング
        $list = $query->orderBy("user.{$sort}", $sortType)->paginate(50);

        // ▼ 画面に渡す（フォーム再描画用に絞り込み値も）
        return view('admin.users.list', [
            'list' => $list,
            'sort' => $sort,
            'sort_type' => $sortType,
            'dir' => $sortType,
            'user_id' => $user_id,
            'member_id' => $member_id,
            'user_tag_serial' => $user_tag_serial,
            'user_phonetic' => $user_phonetic,
            'phone' => $phone,
            'crime' => $crime,
            'email' => $email,
            'tag_qr_flag' => $tag_qr_flag,
            'quit_flag' => $quit_flag,
            'quit_from' => $quit_from,
            'quit_to' => $quit_to,
            'user_category1' => $user_category1,
            'user_category2' => $user_category2,
            'user_category3' => $user_category3,
            'category1Options' => $this->buildCategory1Options(),
            'category2Options' => $this->buildCategory2Options(),
            'category3Options' => $this->buildCategory3Options(),
        ]);
    }

    /**
     * CSV 出力（一覧と同じ絞り込みを適用）
     */
    public function export(Request $request): StreamedResponse
    {
        $q = DB::table('user');

        // ▼ テキスト系
        if (($v = trim((string) $request->input('user_id', ''))) !== '')
            $q->where('user_id', 'like', "%{$v}%");

        if (($v = trim((string) $request->input('user_tag_serial', ''))) !== '')
            $q->where('user_tag_serial', 'like', "%{$v}%");

        if (($v = trim((string) $request->input('user_phonetic', ''))) !== '')
            $q->where('user_phonetic', 'like', "%{$v}%");

        if (($v = trim((string) $request->input('phone', ''))) !== '') {
            $q->where(function ($w) use ($v) {
                $w->where('user_mobile', 'like', "%{$v}%")
                    ->orWhere('user_homephone', 'like', "%{$v}%");
            });
        }

        if (($v = trim((string) $request->input('email', ''))) !== '')
            $q->where('user_primemail', 'like', "%{$v}%");

        // ▼ セレクト/ラジオ（'' だけスキップ。'0' は適用）
        $q->leftJoin('usertype', 'user.user_categoryid', '=', 'usertype.user_categoryid');

        if (($v = trim((string) $request->input('user_category1', ''))) !== '') {
            $q->where('usertype.usertype_subject1', $v);
        }

        if (($v = trim((string) $request->input('user_category2', ''))) !== '') {
            $q->where('usertype.usertype_subject2', $v);
        }

        if (($v = trim((string) $request->input('user_category3', ''))) !== '') {
            $q->where('usertype.usertype_subject3', $v);
        }

        $val = (string) $request->input('tag_qr_flag', '');
        if ($val !== '')
            $q->where('tag_qr_flag', (int) $val);

        $val = (string) $request->input('quit_flag', '');
        if ($val !== '')
            $q->where('user_quit_flag', (int) $val);

        // ▼ 退会日 範囲
        if (($from = (string) $request->input('quit_from', '')) !== '')
            $q->where('user_quitday', '>=', $from);
        if (($to = (string) $request->input('quit_to', '')) !== '')
            $q->where('user_quitday', '<=', $to);

        // ▼ 取得・並び
        $q->orderBy('user_seq', 'desc');

        $rows = $q->get([
            'user_id',
            'tag_qr_flag',
            'user_categoryid',
            'user_name',
            'user_phonetic',
            'user_birthdate',
            'user_age',
            'user_mobile',
            'user_homephone',
            'user_primemail',
            'user_idcard',
            'user_idcard_chk_flag',
            'user_chk_day',
            'user_quit_flag',
            'user_quitday',
        ]);

        $headers = [
            '利用者ID',
            'タグ／ＱＲフラグ',
            '利用者分類ID',
            '利用者名',
            'フリガナ',
            '生年月日',
            '年齢',
            '携帯電話番号',
            '自宅電話番号',
            'メールアドレス',
            '本人確認書類',
            '本人確認チェック済',
            '本人確認日時',
            '退会フラグ',
            '退会日',
        ];

        $filename = 'users_' . date('Ymd_His') . '.csv';

        return response()->streamDownload(function () use ($headers, $rows) {
            // ▼ BOM（Excel対策）
            echo "\xEF\xBB\xBF";
            $out = fopen('php://output', 'w');

            fputcsv($out, $headers);

            foreach ($rows as $r) {
                // ▼ 表示値変換
                $tagQr = ((int) $r->tag_qr_flag === 1) ? 'ＱＲ' : 'タグ';
                $idChk = ((int) ($r->user_idcard_chk_flag ?? 0) === 1) ? '手動チェックOK' : '未チェック';
                $quitFlg = ((int) $r->user_quit_flag === 1) ? 'はい' : 'いいえ';
                $birth = $r->user_birthdate ? mb_substr($r->user_birthdate, 0, 10) : '';
                $chkDay = $r->user_chk_day ? mb_substr($r->user_chk_day, 0, 10) : '';
                $quitDay = $r->user_quitday ? mb_substr($r->user_quitday, 0, 10) : '';

                fputcsv($out, [
                    $r->user_id,
                    $tagQr,
                    $r->user_categoryid,
                    $r->user_name,
                    $r->user_phonetic,
                    $birth,
                    $r->user_age,
                    $r->user_mobile,
                    $r->user_homephone,
                    $r->user_primemail,
                    $r->user_idcard,
                    $idChk,
                    $chkDay,
                    $quitFlg,
                    $quitDay,
                ]);
            }
            fclose($out);
        }, $filename, [
            'Content-Type' => 'text/csv; charset=UTF-8',
            'Content-Disposition' => 'attachment; filename="' . $filename . '"',
        ]);
    }

    /**
     * 利用者登録（GET: 画面表示 / POST: 登録実行）
     * - 必須は最小限（user_id, user_name, user_gender, user_primemail）
     * - created_at/updated_at は DB 側に任せるかここで now() を入れてもOK
     */
    public function add(Request $request)
    {
        if ($request->isMethod('get')) {
            return view('admin.users.add');
        }

        // ▼ バリデーション（user_id は半角数字のみ）
        $rules = [
            'user_id' => ['required', 'regex:/^\d+$/', 'digits_between:1,10'], // 半角数字（最大10桁）
            'user_name' => ['required', 'string', 'max:255'],
            'user_pass' => ['required', 'string', 'min:8', 'confirmed'],
            // 任意
            'user_primemail' => ['nullable', 'email', 'max:255'],
            'user_gender' => ['nullable', 'in:男性,女性'],
            'member_id' => ['nullable', 'string', 'max:255'],
            'user_mobile' => ['nullable', 'string', 'max:255'],
            'user_homephone' => ['nullable', 'string', 'max:255'],
            'user_birthdate' => ['nullable', 'date'],
            'user_categoryid' => ['nullable', 'integer'],
        ];

        // ▼ エラーメッセージ（日本語）
        $messages = [
            'user_id.required' => '利用者IDは必須です。',
            'user_id.regex' => '利用者IDは半角数字のみで入力してください。',
            'user_id.digits_between' => '利用者IDは最大10桁以内で入力してください。',
            'user_name.required' => '氏名は必須です。',
            'user_pass.required' => 'パスワードは必須です。',
            'user_pass.min' => 'パスワードは8文字以上で入力してください。',
            'user_pass.confirmed' => 'パスワードと確認用パスワードが一致しません。',
        ];

        // ▼ 属性名（日本語ラベル）
        $attributes = [
            'user_id' => '利用者ID',
            'user_name' => '氏名',
            'user_gender' => '性別',
            'user_primemail' => '主メール',
        ];

        $v = Validator::make($request->all(), $rules, $messages, $attributes);

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

        // 実在カラム名に合わせて挿入（不要なら削る／必要なら増やす）
        $data = [
            'user_id' => $request->input('user_id'),
            'user_name' => $request->input('user_name'),
            'user_gender' => $request->input('user_gender'),
            'user_primemail' => $request->input('user_primemail'),
            'member_id' => $request->input('member_id'),
            'user_mobile' => $request->input('user_mobile'),
            'user_homephone' => $request->input('user_homephone'),
            'user_birthdate' => $request->input('user_birthdate'),
            'user_categoryid' => $request->input('user_categoryid'),
            'created_at' => now(),
            'updated_at' => now(),
        ];

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

        return redirect()->route('users')->with('success', '利用者を登録しました。');
    }

    /**
     * 利用者編集（GET: 表示 / POST: 更新）
     */
    public function edit(Request $request, int $seq)
    {

        $user = DB::table('user')->where('user_seq', $seq)->first();
        if (!$user) {
            abort(404, '利用者情報が見つかりません。');
        }

        $operators = DB::table('ope')
            ->select('ope_id', 'ope_name')
            ->orderBy('ope_name')
            ->get();

        $categoryOptions = $this->buildCategoryOptions();

        // ▼ 退会処理専用（hiddenフィールド quit_action があれば退会処理）
        if ($request->has('quit_action')) {
            DB::table('user')->where('user_seq', $seq)->update([
                'user_quit_flag' => 1,
                'user_quitday' => now()->format('Y-m-d'),
                'ope_id' => $request->input('ope_id') ?? auth()->user()->ope_id ?? null,
                'updated_at' => now(),
            ]);

            return redirect()
                ->route('users_edit', ['seq' => $seq])
                ->with('status', '退会処理が完了しました。');
        }


        if ($request->isMethod('get')) {
            return view('admin.users.edit', [
                'user' => $user,
                'operators' => $operators,
                'categoryOptions' => $categoryOptions,
            ]);
        }

        $rules = [
            'user_id' => ['required', 'regex:/^\d+$/', 'digits_between:1,10'],
            'user_name' => ['required', 'string', 'max:255'],
            'user_pass' => ['nullable', 'string', 'min:8', 'confirmed'],
            'user_primemail' => ['nullable', 'email', 'max:255'],
            'user_gender' => ['nullable', 'in:男性,女性,未入力'],
            'member_id' => ['nullable', 'string', 'max:255'],
            'user_mobile' => ['nullable', 'string', 'max:255'],
            'user_homephone' => ['nullable', 'string', 'max:255'],
            'user_birthdate' => ['nullable', 'date'],
            'user_categoryid' => ['nullable', 'integer', 'exists:usertype,user_categoryid'],
            'user_age' => ['nullable', 'integer', 'min:0'],
            'user_chk_day' => ['nullable', 'date'],
            'user_quitday' => ['nullable', 'date'],
            'ope_id' => ['nullable', 'integer', 'exists:ope,ope_id'],
        ];

        $messages = [
            'user_id.required' => '利用者IDは必須です。',
            'user_id.regex' => '利用者IDは半角数字のみで入力してください。',
            'user_id.digits_between' => '利用者IDは最大10桁以内で入力してください。',
            'user_name.required' => '氏名は必須です。',
        ];

        $validator = Validator::make($request->all(), $rules, $messages);
        if ($validator->fails()) {
            return back()->withErrors($validator)->withInput();
        }

        $data = [
            'user_id' => $request->input('user_id'),
            'member_id' => $request->input('member_id'),
            'user_name' => $request->input('user_name'),
            'user_gender' => $request->input('user_gender'),
            'user_mobile' => $request->input('user_mobile'),
            'user_homephone' => $request->input('user_homephone'),
            'user_birthdate' => $request->input('user_birthdate'),
            'user_age' => $request->input('user_age'),
            'user_categoryid' => $request->input('user_categoryid'),
            'user_phonetic' => $request->input('user_phonetic'),
            'user_tag_serial' => $request->input('user_tag_serial'),
            'user_tag_serial_64' => $request->input('user_tag_serial_64'),
            'qr_code' => $request->input('qr_code'),
            'tag_qr_flag' => $request->input('tag_qr_flag', '0'),
            'user_aid' => $request->input('user_aid'),
            'user_place_qrid' => $request->input('user_place_qrid'),
            'user_primemail' => $request->input('user_primemail'),
            'user_submail' => $request->input('user_submail'),
            'ward_residents' => $request->input('ward_residents'),
            'user_workplace' => $request->input('user_workplace'),
            'user_school' => $request->input('user_school'),
            'user_graduate' => $request->input('user_graduate'),
            'user_idcard' => $request->input('user_idcard'),
            'user_idcard_chk_flag' => $request->input('user_idcard_chk_flag', '0'),
            'user_chk_day' => $request->input('user_chk_day'),
            'user_chk_opeid' => $request->input('ope_id'),
            'ope_id' => $request->input('ope_id'),
            'user_regident_zip' => $request->input('user_regident_zip'),
            'user_regident_pre' => $request->input('user_regident_pre'),
            'user_regident_city' => $request->input('user_regident_city'),
            'user_regident_add' => $request->input('user_regident_add'),
            'user_relate_zip' => $request->input('user_relate_zip'),
            'user_relate_pre' => $request->input('user_relate_pre'),
            'user_relate_city' => $request->input('user_relate_city'),
            'user_relate_add' => $request->input('user_relate_add'),
            'user_tag_issue' => $request->input('user_tag_issue'),
            'issue_permission' => $request->input('issue_permission', '1'),
            'user_quit_flag' => $request->input('user_quit_flag', '0'),
            'user_quitday' => $request->input('user_quitday'),
            'user_remarks' => $request->input('user_remarks'),
            'updated_at' => now(),
        ];

        if ($request->filled('user_pass')) {
            $data['user_pass'] = Hash::make($request->input('user_pass'));
        }

        DB::table('user')->where('user_seq', $seq)->update($data);

        return redirect()
            ->route('users_edit', ['seq' => $seq])
            ->with('status', '利用者情報を更新しました。');
    }

    /**
     * 利用者削除（POST: 削除実行）
     * - user_seq をキーに削除処理を行う
     * - 削除前に存在確認を行い、存在しない場合はエラーを返す
     * - 削除完了後、一覧画面へリダイレクト
     */
    public function delete(Request $request)
    {
        // ▼ パラメータ取得
        $userSeq = (int) $request->input('user_seq');

        // ▼ 対象レコード存在確認
        $user = DB::table('user')->where('user_seq', $userSeq)->first();
        if (!$user) {
            // 該当データなし
            return redirect()
                ->route('users')
                ->with('error', '利用者情報が見つかりません。');
        }

        // ▼ 削除処理実行
        DB::table('user')->where('user_seq', $userSeq)->delete();

        // ▼ 正常終了メッセージを一覧画面に表示
        return redirect()
            ->route('users')
            ->with('success', '利用者を削除しました。');
    }

}
