<?php

namespace App\Services;

use App\Models\MemInfo;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Carbon;

class MemInfoService
{
    /**
     * CI: set_receive()
     * 프로모션 수신 동의 변경 (행 잠금)
     */
    public function setReceive(int $memNo, string $rcvEmail, string $rcvSms, ?string $rcvPush = null): void
    {
        DB::transaction(function () use ($memNo, $rcvEmail, $rcvSms, $rcvPush) {
            /** @var MemInfo $mem */
            $mem = MemInfo::query()->whereKey($memNo)->lockForUpdate()->firstOrFail();

            $now = Carbon::now()->format('Y-m-d H:i:s');

            $mem->rcv_email = $rcvEmail;
            $mem->rcv_sms = $rcvSms;
            $mem->dt_rcv_email = $now;
            $mem->dt_rcv_sms = $now;

            if ($rcvPush !== null) {
                $mem->rcv_push = $rcvPush;
                $mem->dt_rcv_push = $now;
            }

            $mem->dt_mod = $now;
            $mem->save();
        });
    }

    /**
     * CI: mem_email_vali()
     */
    public function emailInfo(string $email): ?MemInfo
    {
        return MemInfo::query()
            ->select(['mem_no','stat_3','dt_req_out','email'])
            ->where('email', strtolower($email))
            ->first();
    }

    /**
     * CI: mem_reg() (간소화 버전)
     * - 실제로는 validation은 FormRequest에서 처리 권장
     * - stat_3=3 (1969 이전 출생 접근금지) 룰 포함
     */
    public function register(array $data): MemInfo
    {
        return DB::transaction(function () use ($data) {

            $email = strtolower($data['email']);

            // 중복 체크 + 잠금 (CI for update)
            $exists = MemInfo::query()
                ->where('email', $email)
                ->lockForUpdate()
                ->exists();

            if ($exists) {
                throw new \RuntimeException('이미 가입된 아이디 입니다. 다른 아이디로 진행해 주세요.');
            }

            $now = Carbon::now()->format('Y-m-d H:i:s');

            $mem = new MemInfo();
            $mem->email = $email;
            $mem->name = $data['name'] ?? '';
            $mem->pv_sns = $data['pv_sns'] ?? 'self';

            $promotion = !empty($data['promotion']) ? 'y' : 'n';
            $mem->rcv_email = $promotion;
            $mem->rcv_sms = $promotion;
            $mem->rcv_push = $promotion;

            $mem->dt_reg = $now;
            $mem->dt_login = $now;

            $mem->dt_rcv_email = $now;
            $mem->dt_rcv_sms = $now;
            $mem->dt_rcv_push = $now;

            $mem->dt_stat_1 = $now;
            $mem->dt_stat_2 = $now;
            $mem->dt_stat_3 = $now;
            $mem->dt_stat_4 = $now;
            $mem->dt_stat_5 = $now;

            $mem->ip_reg = $data['ip_reg'] ?? request()->ip();

            // 국가/본인인증 값들
            $mem->country_code = $data['country_code'] ?? '';
            $mem->country_name = $data['country_name'] ?? '';
            $mem->birth = $data['birth'] ?? '0000-00-00';
            $mem->cell_corp = $data['cell_corp'] ?? 'n';
            $mem->cell_phone = $data['cell_phone'] ?? ''; // ⚠️ 암호화 저장이라면 여기서 암호화해서 넣어야 함
            $mem->native = $data['native'] ?? 'n';
            $mem->ci = $data['ci'] ?? null;
            $mem->ci_v = $data['ci_v'] ?? '';
            $mem->di = $data['di'] ?? null;
            $mem->gender = $data['gender'] ?? 'n';

            // 1969년 이전 출생 접근금지(stat_3=3)
            $birthY = (int)substr((string)$mem->birth, 0, 4);
            if ($birthY > 0 && $birthY <= 1969) {
                $mem->stat_3 = '3';
            }

            $mem->save();

            return $mem;
        });
    }

    /**
     * CI: last_login()
     */
    public function updateLastLogin(int $memNo): void
    {
        MemInfo::query()
            ->whereKey($memNo)
            ->update([
                'dt_login' => Carbon::now()->format('Y-m-d H:i:s'),
                'login_fail_cnt' => 0,
                'dt_mod' => Carbon::now()->format('Y-m-d H:i:s'),
            ]);
    }

    /**
     * CI: fail_count()
     */
    public function incrementLoginFail(int $memNo): void
    {
        MemInfo::query()
            ->whereKey($memNo)
            ->update([
                'login_fail_cnt' => DB::raw('login_fail_cnt + 1'),
                'dt_mod' => Carbon::now()->format('Y-m-d H:i:s'),
            ]);
    }
}
