<?php
namespace Plugin\NexoraRoulette;

class NexoraPoolStudio {
    private $realm;

    public function __construct($realm) {
        $realm = strtolower(trim((string)$realm));
        if(!in_array($realm,array('legacy','seasonal'),true)) $realm='legacy';
        $this->realm=$realm;
    }

    public static function configPath($realm) {
        $realm = strtolower(trim((string)$realm));
        if(!in_array($realm,array('legacy','seasonal'),true)) $realm='legacy';
        return __PATH_CONFIGS__.'nexoraroulette.poolstudio.'.$realm.'.json';
    }

    public function defaults() {
        return array(
            'version'=>1,
            'campaign_title'=>'Pool activo',
            'campaign_subtitle'=>'Premios de temporada disponibles en este reino.',
            'campaign_starts_at'=>'',
            'campaign_ends_at'=>'',
            'featured_prize_id'=>0,
            'show_campaign'=>1,
            'show_featured'=>1,
            'show_probability_modal'=>1,
            'default_spin_mode'=>'cinematic',
            'quick_spin_ms'=>1800,
            'max_direct_return_ratio'=>0.35,
            'snapshots'=>array(),
        );
    }

    public function load() {
        $data=$this->defaults();
        $path=self::configPath($this->realm);
        if(is_file($path)) {
            $raw=@file_get_contents($path);
            $decoded=is_string($raw)?json_decode($raw,true):null;
            if(is_array($decoded)) $data=array_replace($data,$decoded);
        }
        if(!isset($data['snapshots']) || !is_array($data['snapshots'])) $data['snapshots']=array();
        $data['featured_prize_id']=max(0,(int)$data['featured_prize_id']);
        $data['quick_spin_ms']=max(1200,min(3000,(int)$data['quick_spin_ms']));
        $data['max_direct_return_ratio']=max(0.05,min(1.0,(float)$data['max_direct_return_ratio']));
        $data['default_spin_mode']=($data['default_spin_mode']==='quick')?'quick':'cinematic';
        return $data;
    }

    public function save($input) {
        $current=$this->load();
        $data=$current;
        $data['campaign_title']=$this->text($input['campaign_title']??$current['campaign_title'],80);
        $data['campaign_subtitle']=$this->text($input['campaign_subtitle']??$current['campaign_subtitle'],220);
        $data['campaign_starts_at']=$this->dateValue($input['campaign_starts_at']??'');
        $data['campaign_ends_at']=$this->dateValue($input['campaign_ends_at']??'');
        if($data['campaign_starts_at']!=='' && $data['campaign_ends_at']!=='' && strtotime($data['campaign_ends_at'])<=strtotime($data['campaign_starts_at'])) {
            throw new \InvalidArgumentException('La fecha de fin debe ser posterior al inicio de campaña.');
        }
        $data['featured_prize_id']=max(0,(int)($input['featured_prize_id']??0));
        $data['show_campaign']=!empty($input['show_campaign'])?1:0;
        $data['show_featured']=!empty($input['show_featured'])?1:0;
        $data['show_probability_modal']=!empty($input['show_probability_modal'])?1:0;
        $data['default_spin_mode']=((string)($input['default_spin_mode']??'cinematic')==='quick')?'quick':'cinematic';
        $data['quick_spin_ms']=max(1200,min(3000,(int)($input['quick_spin_ms']??1800)));
        $ratio=(float)($input['max_direct_return_ratio']??0.35);
        if($ratio>1) $ratio=$ratio/100;
        $data['max_direct_return_ratio']=max(0.05,min(1.0,$ratio));
        $this->write($data);
        return $data;
    }

    public function saveSnapshot($label,array $prizes,array $campaign=array()) {
        $data=$this->load();
        $label=$this->text($label,80);
        if($label==='') $label='Copia '.date('Y-m-d H:i');
        $id=date('YmdHis').'-'.substr(bin2hex(random_bytes(4)),0,8);
        $snapshot=array(
            'id'=>$id,
            'label'=>$label,
            'created_at'=>date(DATE_ATOM),
            'prizes'=>array_values($prizes),
            'campaign'=>$campaign,
        );
        array_unshift($data['snapshots'],$snapshot);
        $data['snapshots']=array_slice($data['snapshots'],0,12);
        $this->write($data);
        return $snapshot;
    }

    public function snapshot($id) {
        $data=$this->load();
        foreach($data['snapshots'] as $row) if((string)($row['id']??'')===(string)$id) return $row;
        return null;
    }

    public function deleteSnapshot($id) {
        $data=$this->load();
        $data['snapshots']=array_values(array_filter($data['snapshots'],function($row) use ($id){ return (string)($row['id']??'')!==(string)$id; }));
        $this->write($data);
        return true;
    }

    public function publicConfig() {
        $data=$this->load();
        unset($data['snapshots']);
        $data['campaign_state']=$this->campaignState($data);
        return $data;
    }

    public function campaignState($data=null) {
        if(!is_array($data)) $data=$this->load();
        $now=time();
        $start=trim((string)($data['campaign_starts_at']??''));
        $end=trim((string)($data['campaign_ends_at']??''));
        $startTs=$start!==''?strtotime($start):false;
        $endTs=$end!==''?strtotime($end):false;
        if($startTs!==false && $now<$startTs) return 'scheduled';
        if($endTs!==false && $now>$endTs) return 'ended';
        return 'active';
    }

    private function text($value,$limit) {
        $value=trim(strip_tags((string)$value));
        $length=function_exists('mb_strlen')?mb_strlen($value,'UTF-8'):strlen($value);
        if($length>$limit) $value=function_exists('mb_substr')?mb_substr($value,0,$limit,'UTF-8'):substr($value,0,$limit);
        return $value;
    }

    private function dateValue($value) {
        $value=trim((string)$value);
        if($value==='') return '';
        $ts=strtotime($value);
        if($ts===false) throw new \InvalidArgumentException('Fecha de campaña inválida.');
        return date('Y-m-d\TH:i:s',$ts);
    }

    private function write(array $data) {
        $path=self::configPath($this->realm);
        $dir=dirname($path);
        if(!is_dir($dir) || !is_writable($dir)) throw new \RuntimeException('La carpeta de configuración no permite guardar Pool Studio.');
        $json=json_encode($data,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
        if($json===false) throw new \RuntimeException('No se pudo serializar Pool Studio.');
        $tmp=$path.'.tmp';
        if(file_put_contents($tmp,$json."\n",LOCK_EX)===false) throw new \RuntimeException('No se pudo escribir Pool Studio.');
        if(!@rename($tmp,$path)) { @unlink($tmp); throw new \RuntimeException('No se pudo confirmar la configuración de Pool Studio.'); }
        return true;
    }
}
