<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rule;

class UserEditController extends Controller
{
    // 編集画面表示
    public function show(Request $request)
    {

        $user_id = session('user_id');
        if (!$user_id) {
            return redirect('/login');
        }

        $user = DB::table('user')->where('user_id', $user_id)->first();

        // 利用者区分をusertypeテーブルから取得
        $user_category = '';
        if (isset($user->user_categoryid)) {
            $usertype = DB::table('usertype')
                ->where('user_categoryid', $user->user_categoryid)
                ->first();
            if ($usertype && isset($usertype->usertype_subject1)) {
                $user_category = $usertype->usertype_subject1;
            }
        }

        // 契約・更新期間判定
        $contract = DB::table('regular_contract')
            ->join('park', 'regular_contract.park_id', '=', 'park.park_id')
            ->where('regular_contract.user_id', $user->user_id)
            ->where('regular_contract.contract_flag', 1)
            ->first();

        $today = date('Y-m-d');
        $current_time = date('H:i');
        $is_update_period = true; // デフォルトは編集可能
        $in_contract_period = false;

        if ($contract) {
            $contract_periods = str_replace('/', '-', $contract->contract_periods);
            $contract_periode = str_replace('/', '-', $contract->contract_periode);
            $contract_periods_month = date('Y-m', strtotime($contract_periods));
            $contract_periode_month = date('Y-m', strtotime($contract_periode));
            $current_month = date('Y-m');
            // 契約月が今月の場合
            if ($contract_periods_month === $current_month && $contract_periode_month === $current_month && $contract->contract_flag == 1) {
                $in_contract_period = true;
                $is_update_period = false; // 編集不可
            } else if (strtotime($today) >= strtotime($contract_periods) && strtotime($today) <= strtotime($contract_periode)) {
                $in_contract_period = true;
                $is_update_period = false; // 編集不可
            }
        }
        if ($contract && !$in_contract_period) {
            $city = DB::table('city')->where('city_id', $contract->city_id)->first();
            if ($city) {
                $contract_year = date('Y', strtotime($contract_periode));
                $contract_month = date('m', strtotime($contract_periode));
                $today_year = date('Y');
                $today_month = date('m');
                $today_day = date('d');
                $start_day = (int)$city->update_grace_period_start_date;
                $end_day = (int)$city->update_grace_period_end_date;
                $start_time = $city->update_grace_period_start_time ?? '00:00';
                $end_time = $city->update_grace_period_end_time ?? '23:59';
                $today_time = date('H:i');
                $in_grace = false;

                // 契約終了月のみ猶予期間判定
                if ((int)$today_year === (int)$contract_year) {
                    // 開始日 < 終了日：契約終了月の開始日～終了日
                    if ($start_day < $end_day && (int)$today_month === (int)$contract_month) {
                        $start_datetime = $contract_year . '-' . $contract_month . '-' . sprintf('%02d', $start_day) . ' ' . $start_time;
                        $end_datetime = $contract_year . '-' . $contract_month . '-' . sprintf('%02d', $end_day) . ' ' . $end_time;
                        $today_datetime = date('Y-m-d') . ' ' . $today_time;
                        if (strtotime($today_datetime) >= strtotime($start_datetime) && strtotime($today_datetime) <= strtotime($end_datetime)) {
                            $in_grace = true;
                        }
                    }

                    // 開始日 > 終了日：契約終了月の開始日～翌月の終了日
                    if ($start_day > $end_day) {
                        $start_datetime = $contract_year . '-' . $contract_month . '-' . sprintf('%02d', $start_day) . ' ' . $start_time;
                        $next_month_date = date('Y-m', strtotime($contract_year . '-' . $contract_month . '-01 +1 month'));
                        $end_datetime = $next_month_date . '-' . sprintf('%02d', $end_day) . ' ' . $end_time;
                        $today_datetime = date('Y-m-d') . ' ' . $today_time;
                        if (strtotime($today_datetime) >= strtotime($start_datetime) && strtotime($today_datetime) <= strtotime($end_datetime)) {
                            $in_grace = true;
                        }
                    }
                }
                if ($in_grace) {
                    $is_update_period = false; // 猶予期間も編集不可
                }
            }
        }

        // 必要なら値分解（電話番号・住所等）
        $user->user_homephone = explode('-', $user->user_homephone ?? '');
        $user->user_mobile = explode('-', $user->user_mobile ?? '');
        $user->user_regident_zip_1 = substr($user->user_regident_zip ?? '', 0, 3);
        $user->user_regident_zip_2 = substr($user->user_regident_zip ?? '', 3, 4);
        $user->user_relate_zip_1 = substr($user->user_relate_zip ?? '', 0, 3);
        $user->user_relate_zip_2 = substr($user->user_relate_zip ?? '', 3, 4);

        \Log::info('ユーザー情報編集画面にアクセス', [
            'user_id' => $user_id,
        ]);

        return view('user.edit', [
            'user' => $user,
            'user_category' => $user_category,
            'is_update_period' => $is_update_period,
            'in_contract_period' => $in_contract_period,
            'active_menu' => 'SWC-1-1', // マイページメニューの選択状態用
            'user_name' => $user ? $user->user_name : '', // ユーザー名（ヘッダー用）
        ]);
    }

    // 編集内容保存
    public function update(Request $request)
    {

        $user_id = session('user_id');
        if (!$user_id) {
            return redirect('/login');
        }
        $user = DB::table('user')->where('user_id', $user_id)->first();

        // 編集不可項目はDB値を優先
        // 契約・更新期間判定（showと同じロジックを利用）
        $contract = DB::table('regular_contract')
            ->join('park', 'regular_contract.park_id', '=', 'park.park_id')
            ->where('regular_contract.user_id', $user->user_id)
            ->where('regular_contract.contract_flag', 1)
            ->first();

        $today = date('Y-m-d');
        $current_time = date('H:i');
        $is_update_period = true; // デフォルトは編集可能
        $in_contract_period = false;

        if ($contract) {
            $contract_periods = str_replace('/', '-', $contract->contract_periods);
            $contract_periode = str_replace('/', '-', $contract->contract_periode);
            $contract_periods_month = date('Y-m', strtotime($contract_periods));
            $contract_periode_month = date('Y-m', strtotime($contract_periode));
            $current_month = date('Y-m');
            // 契約月が今月の場合
            if ($contract_periods_month === $current_month && $contract_periode_month === $current_month && $contract->contract_flag == 1) {
                $in_contract_period = true;
                $is_update_period = false; // 編集不可
            } else if (strtotime($today) >= strtotime($contract_periods) && strtotime($today) <= strtotime($contract_periode)) {
                $in_contract_period = true;
                $is_update_period = false; // 編集不可
            }
        }
        if ($contract && !$in_contract_period) {
            $city = DB::table('city')->where('city_id', $contract->city_id)->first();
            if ($city) {
                $contract_year = date('Y', strtotime($contract_periode));
                $contract_month = date('m', strtotime($contract_periode));
                $today_year = date('Y');
                $today_month = date('m');
                $today_day = date('d');
                $start_day = (int)$city->update_grace_period_start_date;
                $end_day = (int)$city->update_grace_period_end_date;
                $start_time = $city->update_grace_period_start_time ?? '00:00';
                $end_time = $city->update_grace_period_end_time ?? '23:59';
                $today_time = date('H:i');
                $in_grace = false;

                // 契約終了月のみ猶予期間判定
                if ((int)$today_year === (int)$contract_year) {
                    // 開始日 < 終了日：契約終了月の開始日～終了日
                    if ($start_day < $end_day && (int)$today_month === (int)$contract_month) {
                        $start_datetime = $contract_year . '-' . $contract_month . '-' . sprintf('%02d', $start_day) . ' ' . $start_time;
                        $end_datetime = $contract_year . '-' . $contract_month . '-' . sprintf('%02d', $end_day) . ' ' . $end_time;
                        $today_datetime = date('Y-m-d') . ' ' . $today_time;
                        if (strtotime($today_datetime) >= strtotime($start_datetime) && strtotime($today_datetime) <= strtotime($end_datetime)) {
                            $in_grace = true;
                        }
                    }

                    // 開始日 > 終了日：契約終了月の開始日～翌月の終了日
                    if ($start_day > $end_day) {
                        $start_datetime = $contract_year . '-' . $contract_month . '-' . sprintf('%02d', $start_day) . ' ' . $start_time;
                        $next_month_date = date('Y-m', strtotime($contract_year . '-' . $contract_month . '-01 +1 month'));
                        $end_datetime = $next_month_date . '-' . sprintf('%02d', $end_day) . ' ' . $end_time;
                        $today_datetime = date('Y-m-d') . ' ' . $today_time;
                        if (strtotime($today_datetime) >= strtotime($start_datetime) && strtotime($today_datetime) <= strtotime($end_datetime)) {
                            $in_grace = true;
                        }
                    }
                }
                if ($in_grace) {
                    $is_update_period = false; // 猶予期間も編集不可
                }
            }
        }

        // バリデーションルール
        $rules = [
            'user_gender' => ['nullable', Rule::in(['男性', '女性'])],
            'user_regident_zip_1' => 'nullable|digits:3',
            'user_regident_zip_2' => 'nullable|digits:4',
            'user_regident_pre' => [
                'nullable',
                Rule::in([
                    '北海道',
                    '青森県',
                    '岩手県',
                    '宮城県',
                    '秋田県',
                    '山形県',
                    '福島県',
                    '茨城県',
                    '栃木県',
                    '群馬県',
                    '埼玉県',
                    '千葉県',
                    '東京都',
                    '神奈川県',
                    '新潟県',
                    '富山県',
                    '石川県',
                    '福井県',
                    '山梨県',
                    '長野県',
                    '岐阜県',
                    '静岡県',
                    '愛知県',
                    '三重県',
                    '滋賀県',
                    '京都府',
                    '大阪府',
                    '兵庫県',
                    '奈良県',
                    '和歌山県',
                    '鳥取県',
                    '島根県',
                    '岡山県',
                    '広島県',
                    '山口県',
                    '徳島県',
                    '香川県',
                    '愛媛県',
                    '高知県',
                    '福岡県',
                    '佐賀県',
                    '長崎県',
                    '熊本県',
                    '大分県',
                    '宮崎県',
                    '鹿児島県',
                    '沖縄県'
                ]),
            ],
            'user_regident_city' => ['nullable', 'string', 'max:20', 'regex:/^(?:(?![\xF0-\xF7][\x80-\xBF]{3}).)*$/'],
            'user_regident_add' => ['nullable', 'string', 'max:50', 'regex:/^(?:(?![\xF0-\xF7][\x80-\xBF]{3}).)*$/'],
            'user_birthdate' => 'nullable|date',
            'user_homephone.*' => 'nullable|digits_between:1,5',
            'user_mobile.*' => 'nullable|digits_between:1,5',
            'user_primemail' => 'required|email|max:80',
            'user_primemail_confirmation' => 'required|same:user_primemail',
            'user_submail' => 'nullable|email|different:user_primemail|max:80',
            'user_category' => ['required', Rule::in(['一般', '学生'])],
            'user_workplace' => ['nullable', 'string', 'max:50', 'regex:/^(?:(?![\xF0-\xF7][\x80-\xBF]{3}).)*$/'],
            'user_school' => ['nullable', 'string', 'max:50', 'regex:/^(?:(?![\xF0-\xF7][\x80-\xBF]{3}).)*$/'],
            'user_graduate' => 'nullable|date',
            'user_relate_zip_1' => 'nullable|digits:3',
            'user_relate_zip_2' => 'nullable|digits:4',
            'user_relate_pre' => [
                'nullable',
                Rule::in([
                    '北海道',
                    '青森県',
                    '岩手県',
                    '宮城県',
                    '秋田県',
                    '山形県',
                    '福島県',
                    '茨城県',
                    '栃木県',
                    '群馬県',
                    '埼玉県',
                    '千葉県',
                    '東京都',
                    '神奈川県',
                    '新潟県',
                    '富山県',
                    '石川県',
                    '福井県',
                    '山梨県',
                    '長野県',
                    '岐阜県',
                    '静岡県',
                    '愛知県',
                    '三重県',
                    '滋賀県',
                    '京都府',
                    '大阪府',
                    '兵庫県',
                    '奈良県',
                    '和歌山県',
                    '鳥取県',
                    '島根県',
                    '岡山県',
                    '広島県',
                    '山口県',
                    '徳島県',
                    '香川県',
                    '愛媛県',
                    '高知県',
                    '福岡県',
                    '佐賀県',
                    '長崎県',
                    '熊本県',
                    '大分県',
                    '宮崎県',
                    '鹿児島県',
                    '沖縄県'
                ]),
            ],
            'user_relate_city' => ['nullable', 'string', 'max:20', 'regex:/^(?:(?![\xF0-\xF7][\x80-\xBF]{3}).)*$/'],
            'user_relate_add' => ['nullable', 'string', 'max:50', 'regex:/^(?:(?![\xF0-\xF7][\x80-\xBF]{3}).)*$/'],
            'photo_filename1' => 'nullable|image|max:4096',
            'photo_filename2' => 'nullable|image|max:4096',
            'user_pass_new' => [
                'nullable',
                'string',
                'min:8',
                'regex:/^[a-zA-Z0-9]+$/', // 半角英数字のみ
            ],
            'user_pass_confirm' => 'nullable|same:user_pass_new',
        ];

        // 利用者区分による必須項目
        if ($request->user_category == '学生') {
            $rules['user_school'] = 'required|string|max:50';
            $rules['user_graduate'] = 'required|date';
        }

        // 編集不可の場合は user_category, user_school, user_graduate の必須チェックを外す
        if (!$is_update_period) {
            $rules['user_category'] = ['nullable', Rule::in(['一般', '学生'])];
            $rules['user_school'] = ['nullable', 'string', 'max:50', 'regex:/^(?:(?![\xF0-\xF7][\x80-\xBF]{3}).)*$/'];
            $rules['user_graduate'] = 'nullable|date';
        }

        $messages = [
            'user_gender.in' => '性別は「男性」または「女性」を選択してください。',
            'user_regident_zip_1.digits' => '居住所の郵便番号（前半3桁）は3桁の数字で入力してください。',
            'user_regident_zip_2.digits' => '居住所の郵便番号（後半4桁）は4桁の数字で入力してください。',
            'user_regident_pre.in' => '都道府県は選択肢から選んでください。',
            'user_regident_city.max' => '居住所の市区町村は20文字以内で入力してください。',
            'user_regident_city.regex' => '居住所の市区町村に絵文字などの特殊文字は使用できません。',
            'user_regident_add.max' => '居住所の住所は50文字以内で入力してください。',
            'user_regident_add.regex' => '居住所の住所に絵文字などの特殊文字は使用できません。',
            'user_birthdate.date' => '生年月日は正しい日付で入力してください。',
            'user_homephone.*.digits_between' => '自宅電話番号はそれぞれ1～5桁の数字で入力してください。',
            'user_mobile.*.digits_between' => '携帯電話番号はそれぞれ1～5桁の数字で入力してください。',
            'user_primemail.required' => 'メールアドレスは必須です。',
            'user_primemail.email' => 'メールアドレスは正しい形式で入力してください。',
            'user_primemail.max' => 'メールアドレスは80文字以内で入力してください。',
            'user_primemail_confirmation.required' => 'メールアドレスの確認は必須です。',
            'user_primemail_confirmation.same' => '「メールアドレス」と「メールアドレスの確認」が一致しません。',
            'user_submail.email' => '予備メールアドレスは正しい形式で入力してください。',
            'user_submail.max' => '予備メールアドレスは80文字以内で入力してください。',
            'user_submail.different' => 'メールアドレスと予備メールアドレスに同じアドレスを入力できません。',
            'user_category.required' => '利用者区分は必須です。',
            'user_category.in' => '利用者区分の値が不正です。',
            'user_workplace.max' => '勤務先は50文字以内で入力してください。',
            'user_workplace.regex' => '勤務先に絵文字などの特殊文字は使用できません。',
            'user_school.max' => '学校名は50文字以内で入力してください。',
            'user_school.required' => '学校名は必須です。',
            'user_school.regex' => '学校名に絵文字などの特殊文字は使用できません。',
            'user_graduate.required' => '卒業年月日は必須です。',
            'user_graduate.date' => '卒業年月日は正しい日付で入力してください。',
            'user_relate_zip_1.digits' => '住所の郵便番号（前半3桁）は3桁の数字で入力してください。',
            'user_relate_zip_2.digits' => '住所の郵便番号（後半4桁）は4桁の数字で入力してください。',
            'user_relate_pre.in' => '住所の都道府県は選択肢から選んでください。',
            'user_relate_city.max' => '住所の市区町村は20文字以内で入力してください。',
            'user_relate_city.regex' => '住所の市区町村に絵文字などの特殊文字は使用できません。',
            'user_relate_add.max' => '住所は50文字以内で入力してください。',
            'user_relate_add.regex' => '住所に絵文字などの特殊文字は使用できません。',
            'photo_filename1.image' => '本人確認書類画像（おもて）は画像ファイルを選択してください。',
            'photo_filename1.max' => '本人確認書類画像（おもて）は4MB以内でアップロードしてください。',
            'photo_filename2.image' => '本人確認書類画像（ウラ）は画像ファイルを選択してください。',
            'photo_filename2.max' => '本人確認書類画像（ウラ）は4MB以内でアップロードしてください。',
            'user_pass_new.min' => '新しいパスワードは8文字以上で入力してください。',
            'user_pass_new.regex' => '新しいパスワードは半角英数字のみで入力してください。',
            'user_pass_confirm.same' => '「新しいパスワード」と「パスワードの確認」が一致しません。',
        ];

        $validated = $request->validate($rules, $messages);

        // 編集不可項目リスト
        $readonly_fields = [
            'user_regident_zip_1',
            'user_regident_zip_2',
            'user_regident_pre',
            'user_regident_city',
            'user_regident_add',
            'user_birthdate',
            'user_workplace',
            'user_school',
            'user_graduate',
            'user_category'
        ];


        if (!$is_update_period) {
            foreach ($readonly_fields as $field) {
                if ($field === 'user_category') {
                    // 利用者区分はusertypeテーブルから取得した文字列を渡す
                    $user_category = '';
                    if (isset($user->user_categoryid)) {
                        $usertype = DB::table('usertype')
                            ->where('user_categoryid', $user->user_categoryid)
                            ->first();
                        if ($usertype && isset($usertype->usertype_subject1)) {
                            $user_category = $usertype->usertype_subject1;
                        }
                    }
                    $request->merge(['user_category' => $user_category]);
                } else if (property_exists($user, $field)) {
                    $request->merge([$field => $user->$field]);
                }
            }
        }

        // 編集不可・可能どちらでも、セッションには最終的な値を保存
        $request->flash();

        // 電話番号結合
        $user->user_homephone = implode('-', $request->input('user_homephone', []));
        $user->user_mobile = implode('-', $request->input('user_mobile', []));

        // 性別
        $user->user_gender = $request->user_gender;

        // 住所結合
        $user->user_regident_zip = $request->user_regident_zip_1 . $request->user_regident_zip_2;
        $user->user_regident_pre = $request->user_regident_pre;
        $user->user_regident_city = $request->user_regident_city;
        $user->user_regident_add = $request->user_regident_add;
        $user->user_relate_zip = $request->user_relate_zip_1 . $request->user_relate_zip_2;
        $user->user_relate_pre = $request->user_relate_pre;
        $user->user_relate_city = $request->user_relate_city;
        $user->user_relate_add = $request->user_relate_add;

        // メール
        $user->user_primemail = $request->user_primemail;
        $user->user_submail = $request->user_submail;

        // 利用者区分
        $user->user_category = $request->user_category;
        $user->user_workplace = $request->user_workplace;
        $user->user_school = $request->user_school;
        $user->user_graduate = $request->user_graduate;

        // 本人確認書類画像
        if ($request->hasFile('photo_filename1')) {
            $file1 = $request->file('photo_filename1');
            $filename1 = uniqid('photo1_') . '.' . $file1->getClientOriginalExtension();
            $file1->storeAs('photo', $filename1, 'public');
            $request->merge(['photo_filename1' => $filename1]);
        }
        if ($request->hasFile('photo_filename2')) {
            $file2 = $request->file('photo_filename2');
            $filename2 = uniqid('photo2_') . '.' . $file2->getClientOriginalExtension();
            $file2->storeAs('photo', $filename2, 'public');
            $request->merge(['photo_filename2' => $filename2]);
        }

        // パスワード（ハッシュ化せず次画面に渡す）
        if ($request->user_pass_new && $request->user_pass_confirm && $request->user_pass_new === $request->user_pass_confirm) {
            $user->password = $request->user_pass_new;
        }

        return redirect()->route('user.confirm')->withInput();
    }
}
