<?php

class AIAutomation extends BaseModel
{
    public function rules(): array
    {
        return $this->db->query("SELECT r.*, u.name created_by_name,
            (SELECT COUNT(*) FROM ai_action_queue q WHERE q.rule_id=r.id AND q.status='proposed') pending_actions
            FROM ai_automation_rules r
            LEFT JOIN users u ON u.id=r.created_by
            ORDER BY r.enabled DESC, r.priority DESC, r.name")->fetchAll();
    }

    public function enabledRules(?string $eventType = null): array
    {
        $sql = "SELECT * FROM ai_automation_rules WHERE enabled=1";
        $params = [];
        if ($eventType) {
            $sql .= " AND event_type IN (?, 'scheduled')";
            $params[] = $eventType;
        }
        $sql .= " ORDER BY priority DESC, id";
        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        return $stmt->fetchAll();
    }

    public function findRule(int $id): ?array
    {
        $stmt = $this->db->prepare('SELECT * FROM ai_automation_rules WHERE id=?');
        $stmt->execute([$id]);
        return $stmt->fetch() ?: null;
    }

    public function saveRule(array $data, ?int $id = null): int
    {
        $name = trim((string)($data['name'] ?? ''));
        if ($name === '') throw new InvalidArgumentException('Rule name is required.');
        $eventType = in_array(($data['event_type'] ?? ''), ['scheduled','load_exception','document_missing','reefer_alert','fuel_exception','hos_risk','border_delay','invoice_overdue','carrier_compliance'], true)
            ? $data['event_type'] : 'scheduled';
        $mode = in_array(($data['execution_mode'] ?? ''), ['recommend_only','auto_safe'], true) ? $data['execution_mode'] : 'recommend_only';
        $frequency = in_array(($data['frequency'] ?? ''), ['hourly','every_4_hours','daily','manual'], true) ? $data['frequency'] : 'daily';
        $roles = array_values(array_intersect((array)($data['target_roles'] ?? []), ['owner','admin','dispatcher','accountant','maintenance','team','carrier']));
        if (!$roles) $roles = ['owner','admin'];
        $config = [
            'lookahead_hours' => max(1, min(168, (int)($data['lookahead_hours'] ?? 24))),
            'grace_minutes' => max(0, min(1440, (int)($data['grace_minutes'] ?? 30))),
            'create_task' => !empty($data['create_task']),
            'send_notification' => !empty($data['send_notification']),
            'use_ai_summary' => !empty($data['use_ai_summary']),
            'target_roles' => $roles,
        ];
        $values = [
            $name,
            trim((string)($data['description'] ?? '')) ?: null,
            $eventType,
            $mode,
            $frequency,
            max(1, min(100, (int)($data['priority'] ?? 50))),
            !empty($data['enabled']) ? 1 : 0,
            json_encode($config, JSON_UNESCAPED_SLASHES),
        ];
        if ($id) {
            $values[] = $id;
            $this->db->prepare('UPDATE ai_automation_rules SET name=?,description=?,event_type=?,execution_mode=?,frequency=?,priority=?,enabled=?,config_json=?,updated_at=NOW() WHERE id=?')->execute($values);
            return $id;
        }
        $values[] = Auth::user()['id'] ?? null;
        $this->db->prepare('INSERT INTO ai_automation_rules (name,description,event_type,execution_mode,frequency,priority,enabled,config_json,created_by) VALUES (?,?,?,?,?,?,?,?,?)')->execute($values);
        return (int)$this->db->lastInsertId();
    }

    public function toggleRule(int $id, bool $enabled): void
    {
        $this->db->prepare('UPDATE ai_automation_rules SET enabled=?,updated_at=NOW() WHERE id=?')->execute([$enabled ? 1 : 0, $id]);
    }

    public function startRun(?int $ruleId, string $source, ?int $userId): int
    {
        $stmt = $this->db->prepare("INSERT INTO ai_automation_runs (rule_id,status,trigger_source,started_at,initiated_by) VALUES (?,'running',?,NOW(),?)");
        $stmt->execute([$ruleId, $source, $userId]);
        return (int)$this->db->lastInsertId();
    }

    public function finishRun(int $runId, string $status, string $summary, int $scanned, int $proposed, int $executed, ?string $error = null): void
    {
        $stmt = $this->db->prepare('UPDATE ai_automation_runs SET status=?,summary=?,items_scanned=?,actions_proposed=?,actions_executed=?,error_message=?,completed_at=NOW() WHERE id=?');
        $stmt->execute([$status, $summary ?: null, $scanned, $proposed, $executed, $error ? substr($error, 0, 2000) : null, $runId]);
    }

    public function touchRule(int $ruleId): void
    {
        $this->db->prepare('UPDATE ai_automation_rules SET last_run_at=NOW() WHERE id=?')->execute([$ruleId]);
    }

    public function createAction(array $data): int
    {
        $stmt = $this->db->prepare("INSERT INTO ai_action_queue
            (run_id,rule_id,action_type,entity_type,entity_id,title,description,payload_json,risk_level,status,requires_approval,created_by_ai)
            VALUES (?,?,?,?,?,?,?,?,?,'proposed',?,1)");
        $stmt->execute([
            $data['run_id'] ?? null,
            $data['rule_id'] ?? null,
            substr((string)$data['action_type'], 0, 80),
            substr((string)($data['entity_type'] ?? ''), 0, 60) ?: null,
            !empty($data['entity_id']) ? (int)$data['entity_id'] : null,
            substr(trim((string)$data['title']), 0, 190),
            trim((string)($data['description'] ?? '')) ?: null,
            json_encode($data['payload'] ?? [], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE),
            in_array(($data['risk_level'] ?? ''), ['low','medium','high','critical'], true) ? $data['risk_level'] : 'medium',
            !empty($data['requires_approval']) ? 1 : 0,
        ]);
        return (int)$this->db->lastInsertId();
    }

    public function action(int $id): ?array
    {
        $stmt = $this->db->prepare('SELECT q.*, r.name rule_name FROM ai_action_queue q LEFT JOIN ai_automation_rules r ON r.id=q.rule_id WHERE q.id=?');
        $stmt->execute([$id]);
        return $stmt->fetch() ?: null;
    }

    public function actions(string $status = '', int $limit = 100): array
    {
        $sql = 'SELECT q.*,r.name rule_name,approver.name approved_by_name FROM ai_action_queue q LEFT JOIN ai_automation_rules r ON r.id=q.rule_id LEFT JOIN users approver ON approver.id=q.approved_by';
        $params=[];
        if ($status !== '') { $sql .= ' WHERE q.status=?'; $params[]=$status; }
        $sql .= ' ORDER BY FIELD(q.status,\'proposed\',\'approved\',\'failed\',\'executed\',\'rejected\',\'skipped\'), FIELD(q.risk_level,\'critical\',\'high\',\'medium\',\'low\'), q.id DESC LIMIT '.max(1,min(250,$limit));
        $stmt=$this->db->prepare($sql);$stmt->execute($params);return $stmt->fetchAll();
    }

    public function setActionStatus(int $id, string $status, ?int $userId = null, ?string $error = null): void
    {
        $allowed=['approved','rejected','executed','failed','skipped'];
        if(!in_array($status,$allowed,true)) return;
        $fields='status=?,error_message=?';$params=[$status,$error?substr($error,0,2000):null];
        if(in_array($status,['approved','rejected'],true)){$fields.=',approved_by=?,approved_at=NOW()';$params[]=$userId;}
        if(in_array($status,['executed','failed'],true)){$fields.=',executed_by=?,executed_at=NOW()';$params[]=$userId;}
        $params[]=$id;$this->db->prepare("UPDATE ai_action_queue SET {$fields} WHERE id=?")->execute($params);
    }

    public function logChange(array $data): int
    {
        $stmt=$this->db->prepare('INSERT INTO ai_change_log (action_id,user_id,change_type,entity_type,entity_id,title,before_json,after_json,message) VALUES (?,?,?,?,?,?,?,?,?)');
        $stmt->execute([
            $data['action_id']??null,$data['user_id']??null,substr((string)$data['change_type'],0,80),
            substr((string)($data['entity_type']??''),0,60)?:null,!empty($data['entity_id'])?(int)$data['entity_id']:null,
            substr((string)$data['title'],0,190),
            isset($data['before'])?json_encode($data['before'],JSON_UNESCAPED_SLASHES):null,
            isset($data['after'])?json_encode($data['after'],JSON_UNESCAPED_SLASHES):null,
            trim((string)($data['message']??''))?:null,
        ]);
        return (int)$this->db->lastInsertId();
    }

    public function recentChanges(int $limit=80): array
    {
        $stmt=$this->db->query('SELECT c.*,u.name user_name,q.action_type FROM ai_change_log c LEFT JOIN users u ON u.id=c.user_id LEFT JOIN ai_action_queue q ON q.id=c.action_id ORDER BY c.id DESC LIMIT '.max(1,min(250,$limit)));
        return $stmt->fetchAll();
    }

    public function recentRuns(int $limit=30): array
    {
        return $this->db->query('SELECT x.*,r.name rule_name,u.name initiated_by_name FROM ai_automation_runs x LEFT JOIN ai_automation_rules r ON r.id=x.rule_id LEFT JOIN users u ON u.id=x.initiated_by ORDER BY x.id DESC LIMIT '.max(1,min(100,$limit)))->fetchAll();
    }

    public function stats(): array
    {
        $stats=['enabled_rules'=>0,'pending_actions'=>0,'executed_24h'=>0,'failed_24h'=>0,'changes_24h'=>0];
        foreach([
            'enabled_rules'=>'SELECT COUNT(*) FROM ai_automation_rules WHERE enabled=1',
            'pending_actions'=>"SELECT COUNT(*) FROM ai_action_queue WHERE status='proposed'",
            'executed_24h'=>"SELECT COUNT(*) FROM ai_action_queue WHERE status='executed' AND executed_at>=DATE_SUB(NOW(),INTERVAL 24 HOUR)",
            'failed_24h'=>"SELECT COUNT(*) FROM ai_action_queue WHERE status='failed' AND executed_at>=DATE_SUB(NOW(),INTERVAL 24 HOUR)",
            'changes_24h'=>'SELECT COUNT(*) FROM ai_change_log WHERE created_at>=DATE_SUB(NOW(),INTERVAL 24 HOUR)',
        ] as $key=>$sql){try{$stats[$key]=(int)$this->db->query($sql)->fetchColumn();}catch(Throwable $e){}}
        return $stats;
    }
}
