<?php

namespace App\Repositories\Admin\Sms;

use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;

final class AdminSmsBatchRepository
{
    public function insertBatch(array $data): int
    {
        $now = now();

        return (int) DB::table('admin_sms_batches')->insertGetId([
            'admin_user_id'   => (int)($data['admin_user_id'] ?? 0),
            'from_number'     => (string)($data['from_number'] ?? ''),
            'send_mode'       => (string)($data['send_mode'] ?? 'one'),
            'schedule_type'   => (string)($data['schedule_type'] ?? 'now'),
            'scheduled_at'    => $data['scheduled_at'] ?? null,

            'message_raw'     => (string)($data['message_raw'] ?? ''),
            'byte_len'        => (int)($data['byte_len'] ?? 0),
            'sms_type_hint'   => (string)($data['sms_type_hint'] ?? 'auto'),

            'total_count'     => (int)($data['total_count'] ?? 0),
            'valid_count'     => (int)($data['valid_count'] ?? 0),
            'duplicate_count' => (int)($data['duplicate_count'] ?? 0),
            'invalid_count'   => (int)($data['invalid_count'] ?? 0),

            'status'          => (string)($data['status'] ?? 'queued'),

            'request_ip'      => $data['request_ip'] ?? null,
            'user_agent'      => $data['user_agent'] ?? null,
            'error_message'   => $data['error_message'] ?? null,

            'created_at'      => $now,
            'updated_at'      => $now,
        ]);
    }

    /**
     * items: [['seq'=>1,'to_number'=>'010...','message_final'=>'...','sms_type'=>'sms','status'=>'queued', ...], ...]
     */
    public function insertItemsChunked(int $batchId, array $items, int $chunkSize = 1000): void
    {
        $now = now();
        $buf = [];

        foreach ($items as $it) {
            $buf[] = [
                'batch_id'         => $batchId,
                'seq'              => (int)($it['seq'] ?? 0),
                'to_number'        => (string)($it['to_number'] ?? ''),
                'message_final'    => (string)($it['message_final'] ?? ''),
                'sms_type'         => (string)($it['sms_type'] ?? 'sms'),
                'status'           => (string)($it['status'] ?? 'queued'),
                'provider'         => (string)($it['provider'] ?? 'lguplus'),
                'provider_msg_id'  => $it['provider_msg_id'] ?? null,
                'provider_code'    => $it['provider_code'] ?? null,
                'provider_message' => $it['provider_message'] ?? null,
                'submitted_at'     => $it['submitted_at'] ?? null,
                'created_at'       => $now,
                'updated_at'       => $now,
            ];

            if (count($buf) >= $chunkSize) {
                DB::table('admin_sms_batch_items')->insert($buf);
                $buf = [];
            }
        }

        if (!empty($buf)) {
            DB::table('admin_sms_batch_items')->insert($buf);
        }
    }

    public function updateBatch(int $batchId, array $data): int
    {
        $data['updated_at'] = now();
        return (int) DB::table('admin_sms_batches')->where('id', $batchId)->update($data);
    }

    public function updateItemBySeq(int $batchId, int $seq, array $data): int
    {
        $data['updated_at'] = now();
        return (int) DB::table('admin_sms_batch_items')
            ->where('batch_id', $batchId)
            ->where('seq', $seq)
            ->update($data);
    }

    public function findBatch(int $batchId): ?object
    {
        return DB::table('admin_sms_batches')->where('id', $batchId)->first();
    }

    public function paginateBatches(array $filters, int $perPage = 30): LengthAwarePaginator
    {
        $q = DB::table('admin_sms_batches as b')
            ->leftJoin('admin_users as au', 'au.id', '=', 'b.admin_user_id')
            ->select([
                'b.*',
                DB::raw('COALESCE(au.nickname, au.name, au.email) as admin_name'),
                DB::raw('au.email as admin_email'),
            ])
            ->orderByDesc('b.id');

        if (!empty($filters['status'])) {
            $q->where('b.status', (string)$filters['status']);
        }
        if (!empty($filters['send_mode'])) {
            $q->where('b.send_mode', (string)$filters['send_mode']);
        }
        if (!empty($filters['q'])) {
            $kw = '%' . (string)$filters['q'] . '%';
            $q->where(function ($w) use ($kw) {
                $w->where('b.message_raw', 'like', $kw)
                    ->orWhere('b.from_number', 'like', $kw)
                    ->orWhere('b.request_ip', 'like', $kw);
            });
        }
        if (!empty($filters['date_from'])) {
            $q->where('b.created_at', '>=', $filters['date_from'] . ' 00:00:00');
        }
        if (!empty($filters['date_to'])) {
            $q->where('b.created_at', '<=', $filters['date_to'] . ' 23:59:59');
        }

        return $q->paginate($perPage)->withQueryString();
    }

    public function paginateItems(int $batchId, array $filters, int $perPage = 50): LengthAwarePaginator
    {
        $q = DB::table('admin_sms_batch_items')
            ->where('batch_id', $batchId)
            ->orderBy('seq');

        if (!empty($filters['status'])) {
            $q->where('status', (string)$filters['status']);
        }
        if (!empty($filters['to'])) {
            $to = preg_replace('/\D+/', '', (string)$filters['to']);
            if ($to !== '') $q->where('to_number', 'like', '%' . $to . '%');
        }
        if (!empty($filters['q'])) {
            $kw = '%' . (string)$filters['q'] . '%';
            $q->where('message_final', 'like', $kw);
        }

        return $q->paginate($perPage)->withQueryString();
    }
}
