<?php
namespace app\adminVue\controller;

use think\facade\Db;
use think\exception\HttpResponseException;
use app\mobile\service\TemplateFailureMonitor;
use app\mobile\service\WechatTemplateService;

/** 新版后台独立页面；实时校验当前账号，异常详情仅系统管理员可见。 */
class V2TemplateFailures extends V2Base
{
    protected $failureAdmin;
    protected function initialize() {
        parent::initialize();
        $this->failureAdmin=$this->actor;
        if ((int)$this->actor['rightid']<99) $this->reject('仅系统管理员可查看消息异常',403);
    }
    private function reject($message,$status=400) { throw new HttpResponseException(json(['code'=>1,'msg'=>$message,'data'=>null],$status)); }
    private function result($data,$message='') { return json(['code'=>0,'msg'=>$message,'data'=>$data]); }
    private function integer($value,$max=2147483647) {
        if ((!is_string($value)&&!is_int($value)) || !preg_match('/^[1-9][0-9]{0,9}$/D',(string)$value) || (float)$value>$max) $this->reject('数字参数不正确');
        return (int)$value;
    }
    private function present($row) {
        unset($row['open_key'],$row['recipient_hash']);
        foreach (['id','occurrences','status','error_code','http_status','curl_errno','first_at','last_at','last_alert_at','last_alert_attempt_at','alerted_occurrences','resolved_at','resolved_by'] as $key) $row[$key]=(int)$row[$key];
        $row['template_name']=TemplateFailureMonitor::title($row['template_key']);
        $row['alert_pending']=$row['status']===0 && $row['occurrences']>$row['alerted_occurrences'];
        return $row;
    }
    public function overview() {
        $subscribed=(int)Db::name('template_alert_subscriber')->where('admin_id',$this->failureAdmin['id'])->value('enabled')===1;
        $bound=(bool)app()->make(WechatTemplateService::class)->admins([$this->failureAdmin['id']]);
        return $this->result(['openCount'=>Db::name('template_failure')->where('status',0)->count(),
            'totalCount'=>Db::name('template_failure')->count(),
            'pendingAlerts'=>Db::name('template_failure')->where('status',0)->whereRaw('alerted_occurrences < occurrences')->count(),
            'subscribed'=>$subscribed,'bound'=>$bound]);
    }
    public function index() {
        $page=$this->integer($this->request->get('page',1));$limit=$this->integer($this->request->get('limit',20),100);
        $query=Db::name('template_failure');$status=$this->request->get('status','0');
        if (!is_scalar($status) || !in_array((string)$status,['','0','1'],true)) $this->reject('状态参数不正确');
        if ((string)$status!=='') $query->where('status',(int)$status);
        foreach (['template'=>'template_key','stage'=>'stage'] as $param=>$field) {
            $value=$this->request->get($param,'');if (!is_string($value)||strlen($value)>64) $this->reject('筛选参数不正确');
            if ($value!=='') $query->where($field,$value);
        }
        $keyword=$this->request->get('keyword','');if (!is_string($keyword)||mb_strlen($keyword)>100) $this->reject('关键词过长');
        if (trim($keyword)!=='') $query->whereLike('business_no|error_message|recipient_label','%'.addcslashes(trim($keyword),'%_\\').'%');
        $total=(clone $query)->count();$rows=$query->order('last_at desc,id desc')->page($page,$limit)->select()->toArray();
        return $this->result(['list'=>array_map([$this,'present'],$rows),'total'=>$total]);
    }
    public function detail() {
        $row=Db::name('template_failure')->find($this->integer($this->request->get('id')));if (!$row) $this->reject('记录不存在',404);
        $result=$this->present($row);$result['resolver_name']=$row['resolved_by']?Db::name('admin_user')->where('id',$row['resolved_by'])->value('truename'):'';
        return $this->result($result);
    }
    public function resolve() {
        $id=$this->integer($this->request->post('id'));$count=$this->integer($this->request->post('occurrences'));
        $note=$this->request->post('note','');if (!is_string($note)||trim($note)===''||mb_strlen($note)>500) $this->reject('请填写处理说明，最多500字');
        $changed=Db::name('template_failure')->where(['id'=>$id,'status'=>0,'occurrences'=>$count])->update([
            'status'=>1,'open_key'=>null,'resolved_at'=>time(),'resolved_by'=>$this->failureAdmin['id'],'resolution_note'=>trim($note)]);
        if (!$changed) $this->reject('记录已处理或又出现新错误，请刷新后核对',409);
        return $this->result(null,'已标记处理；原业务通知不会自动重发');
    }
    public function subscribe() {
        $enabled=$this->request->post('enabled');if (!is_bool($enabled)&&!in_array($enabled,[0,1,'0','1'],true)) $this->reject('订阅参数不正确');
        if ($enabled && !app()->make(WechatTemplateService::class)->admins([$this->failureAdmin['id']])) $this->reject('当前账号尚未绑定服务号，请先在新版小程序完成绑定');
        Db::name('template_alert_subscriber')->replace()->insert(['admin_id'=>$this->failureAdmin['id'],'enabled'=>(int)(bool)$enabled,'updated_at'=>time()]);
        return $this->result(['enabled'=>(bool)$enabled],$enabled?'已接收当前账号的服务号故障提醒':'已关闭当前账号的服务号故障提醒');
    }
    public function retryAlerts() {
        $count=app()->make(TemplateFailureMonitor::class)->notifyPending(app()->make(WechatTemplateService::class),3,60);
        return $this->result(['sent'=>$count],'已尝试推送'.$count.'条故障提醒；同类提醒至少间隔1分钟，业务原消息不会重发');
    }
}
