<?php

namespace App\Models\Entities;

use CodeIgniter\Model;

/**
 * V2UrlImgSaveModel
 * 
 * v2_url_img_save 테이블 - URL 이미지 저장 관리
 * 홍보 및 등기 이미지 URL을 수신하여 저장 상태를 관리하는 테이블
 */
class V2urlimgsaveModel extends Model
{
    protected $table            = 'v2_url_img_save';
    protected $primaryKey       = 'pk';
    protected $useAutoIncrement = true;
    protected $returnType       = 'array';
    protected $useSoftDeletes   = false;
    protected $allowedFields    = [
        'pk',
        'url',
        'type',
        'atcl_no',
        'vr_sq',
        'status',
        'try_cnt',
        'insert_dt',
        'server_nm',
    ];

    // 검증 규칙
    protected $validationRules    = [
        'url'       => 'string',
        'type'      => 'in_list[1,2]',
        'atcl_no'   => 'string|max_length[10]',
        'vr_sq'     => 'integer',
        'status'    => 'in_list[save,ing,done,err]',
        'try_cnt'   => 'integer|less_than_equal_to[3]',
        'insert_dt' => 'valid_date',
        'server_nm' => 'string|max_length[20]',
    ];

    protected $validationMessages = [];
    protected $skipValidation     = false;
    protected $cleanValidationRules = true;

    // 콜백
    protected $allowCallbacks = true;
    protected $beforeInsert   = ['setInsertDate'];
    protected $afterInsert    = [];
    protected $beforeUpdate   = [];
    protected $afterUpdate    = [];
    protected $beforeFind     = [];
    protected $afterFind      = [];
    protected $beforeDelete   = [];
    protected $afterDelete    = [];

    /**
     * 삽입 전 insert_dt 자동 설정
     */
    protected function setInsertDate(array $data)
    {
        if (!isset($data['data']['insert_dt'])) {
            $data['data']['insert_dt'] = date('Y-m-d H:i:s');
        }
        return $data;
    }

    /**
     * 상태별 데이터 조회 (save, ing, done, err)
     */
    public function getByStatus(string $status): array
    {
        return $this->where('status', $status)->findAll();
    }

    /**
     * vr_sq로 데이터 조회
     */
    public function getByVrSq(int $vrSq): array
    {
        return $this->where('vr_sq', $vrSq)->findAll();
    }

    /**
     * type과 vr_sq로 데이터 조회
     */
    public function getByTypeAndVrSq(string $type, int $vrSq): array
    {
        return $this->where('type', $type)
                    ->where('vr_sq', $vrSq)
                    ->findAll();
    }

    /**
     * atcl_no로 데이터 조회
     */
    public function getByAtclNo(string $atclNo): array
    {
        return $this->where('atcl_no', $atclNo)->findAll();
    }

    /**
     * 저장 대기 중인 데이터 조회 (save 상태)
     */
    public function getPendingSave(): array
    {
        return $this->where('status', 'save')
                    ->where('try_cnt <', 3)
                    ->orderBy('insert_dt', 'ASC')
                    ->findAll();
    }

    /**
     * 저장 중인 데이터 조회 (ing 상태)
     */
    public function getSaving(): array
    {
        return $this->where('status', 'ing')->findAll();
    }

    /**
     * 저장 실패 데이터 조회 (err 상태)
     */
    public function getErrors(): array
    {
        return $this->where('status', 'err')->findAll();
    }

    /**
     * 특정 이미지 상태 업데이트
     */
    public function updateStatus(int $pk, string $status): bool
    {
        return $this->update($pk, ['status' => $status]);
    }

    /**
     * 재시도 횟수 증가
     */
    public function incrementTryCount(int $pk): bool
    {
        $current = $this->find($pk);
        if (!$current) {
            return false;
        }

        $tryCount = ($current['try_cnt'] ?? 0) + 1;
        $status = $tryCount >= 3 ? 'err' : 'save';

        return $this->update($pk, [
            'try_cnt' => $tryCount,
            'status'  => $status,
        ]);
    }

    /**
     * 저장 완료 처리
     */
    public function markAsDone(int $pk): bool
    {
        return $this->update($pk, ['status' => 'done']);
    }

    /**
     * 저장 중 표시
     */
    public function markAsProcessing(int $pk): bool
    {
        return $this->update($pk, ['status' => 'ing']);
    }

    /**
     * 저장 실패 표시
     */
    public function markAsError(int $pk): bool
    {
        return $this->update($pk, ['status' => 'err']);
    }

    /**
     * 특정 vr_sq의 모든 이미지 저장 완료
     */
    public function markAllDoneByVrSq(int $vrSq): bool
    {
        return $this->where('vr_sq', $vrSq)
                    ->set(['status' => 'done'])
                    ->update();
    }

    /**
     * type별 통계
     */
    public function getStatisticsByType(int $vrSq): array
    {
        $result = [
            '1' => ['total' => 0, 'done' => 0, 'ing' => 0, 'save' => 0, 'err' => 0],
            '2' => ['total' => 0, 'done' => 0, 'ing' => 0, 'save' => 0, 'err' => 0],
        ];

        $records = $this->where('vr_sq', $vrSq)->findAll();

        foreach ($records as $record) {
            $type = $record['type'];
            if (!isset($result[$type])) {
                continue;
            }

            $result[$type]['total']++;
            $status = $record['status'];
            if (isset($result[$type][$status])) {
                $result[$type][$status]++;
            }
        }

        return $result;
    }

    /**
     * 저장할 준비된 데이터 조회 (제한 개수)
     */
    public function getNextBatch(int $limit = 10): array
    {
        return $this->where('status', 'save')
                    ->where('try_cnt <', 3)
                    ->orderBy('insert_dt', 'ASC')
                    ->limit($limit)
                    ->findAll();
    }
}
