<?php

namespace App\Services;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;

class SmsService
{
    private string $companyName = 'lguplus';

    /**
     * @param array $payload
     *  - from_number (필수)
     *  - to_number   (필수)
     *  - message     (필수)
     *  - subject     (mms일 때 없으면 자동 생성)
     *  - sms_type    (sms|mms) (없으면 길이로 판단)
     *  - country     (없으면 세션/기본 82)
     *  - scheduled_at (옵션) : 'Y-m-d H:i' 또는 'Y-m-d H:i:s' (미래면 예약, 아니면 즉시)
     *
     * @param string|null $companyName
     * @return bool
     */
    public function send(array $payload, ?string $companyName = null): bool
    {
        try {
            if ($companyName) {
                $this->companyName = $companyName;
            }

            // 1) 필수값 체크 (CI의 Param_exception 대체)
            if (empty($payload['from_number'])) return false;
            if (empty($payload['to_number'])) return false;
            if (empty($payload['message'])) return false;

            // 2) country 결정 (CI sess['_mcountry_code'] 로직 대응)
            $country = $payload['country'] ?? null;

            if ($country === null) {
                $sessCountry = Session::get('_mcountry_code'); // 기존 키 그대로 사용
                if (!empty($sessCountry)) {
                    $country = ($sessCountry === '82' || $sessCountry === '') ? '82' : $sessCountry;
                }
            }
            $payload['country'] = $country ?: '82';

            // 3) 수신번호 체크/정리
            if (!$this->phoneNumberCheck($payload)) {
                return false;
            }

            // 4) 업체별 발송 (실제는 업체 DB insert)
            return match ($this->companyName) {
                'lguplus' => $this->lguplusSend($payload),
                'sms2'    => $this->sms2Send($payload),
                default   => false,
            };
        } catch (\Throwable $e) {
            return false;
        }
    }

    /**
     * CI: phonenumber_check 로직 이식
     * - country=82면 숫자만 남기고 01xxxxxxxxx 형식만 허용
     */
    private function phoneNumberCheck(array &$payload): bool
    {
        if (($payload['country'] ?? '82') === '82') {
            $num = preg_replace("/[^0-9]/", "", $payload['to_number'] ?? '');
            if (preg_match("/^01[0-9]{8,9}$/", $num)) {
                $payload['to_number'] = $num;
                return true;
            }
            return false;
        }

        // 해외는 CI 원본처럼 그냥 통과(필요하면 국가별 검증 로직 추가)
        return true;
    }

    /**
     * ✅ 예약시간 처리(CI3 로직 그대로)
     * - scheduled_at이 없으면 now()
     * - 'Y-m-d H:i'면 ':00' 붙임
     * - 미래면 그 시간, 과거/형식오류면 now()
     */
    private function resolveProviderSendDate(?string $scheduledAt): string
    {
        $now = now()->format('Y-m-d H:i:s');
        if (!$scheduledAt) return $now;

        $scheduled = trim($scheduledAt);

        // 폼은 Y-m-d H:i 로 오니 :00 붙임
        if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/', $scheduled)) {
            $scheduled .= ':00';
        }

        if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $scheduled)) {
            if (strtotime($now) < strtotime($scheduled)) {
                return $scheduled; // 미래면 예약
            }
        }

        return $now; // 과거/형식오류면 즉시
    }

    /**
     * CI: lguplus_send 이식
     * - 메시지 길이(EUC-KR) 기준 90 이하 sms, 초과 mms
     * - sms_type이 명시되면 그걸 우선
     * - ✅ scheduled_at이 미래면 업체 예약 컬럼에 해당 시간으로 insert
     *    - SMS: SC_TRAN.TR_SENDDATE
     *    - MMS: MMS_MSG.REQDATE
     */
    private function lguplusSend(array $data): bool
    {
        $conn = DB::connection('sms_server');
        $smsSendType = $this->resolveSendType($data);

        // ✅ 예약/즉시 결정
        $sendDate = $this->resolveProviderSendDate($data['scheduled_at'] ?? null);

        return (bool) $conn->transaction(function () use ($conn, $smsSendType, $data, $sendDate) {

            if ($smsSendType === 'sms') {
                return $conn->table('SC_TRAN')->insert([
                    'TR_SENDDATE'  => $sendDate,
                    'TR_SENDSTAT'  => '0',
                    'TR_MSGTYPE'   => '0',
                    'TR_PHONE'     => $data['to_number'],
                    'TR_CALLBACK'  => $data['from_number'],
                    'TR_MSG'       => $data['message'],
                ]);
            }

            $subject = $data['subject'] ?? mb_substr($data['message'], 0, 22, 'UTF-8');

            return $conn->table('MMS_MSG')->insert([
                'SUBJECT'    => $subject,
                'PHONE'      => $data['to_number'],
                'CALLBACK'   => $data['from_number'],
                'STATUS'     => '0',
                'REQDATE'    => $sendDate,
                'MSG'        => $data['message'],
                'FILE_CNT'   => 0,
                'FILE_PATH1' => '',
                'TYPE'       => '0',
            ]);
        });
    }

    private function resolveSendType(array $data): string
    {
        // CI 로직과 동일한 우선순위 유지
        if (!empty($data['sms_type'])) {
            if ($data['sms_type'] === 'sms') {
                return (mb_strlen($data['message'], 'EUC-KR') <= 90) ? 'sms' : 'mms';
            }
            return 'mms';
        }

        return (mb_strlen($data['message'], 'EUC-KR') <= 90) ? 'sms' : 'mms';
    }

    private function sms2Send(array $data): bool
    {
        // TODO: 업체 연동 시 구현
        return true;
    }
}
