#!/usr/bin/env python3
"""CorvOS v1.0.5-ASI - Sistema Completo - Corrigido"""
import numpy as np
from scipy.linalg import eig
from dataclasses import dataclass
from typing import Dict,List
from datetime import datetime
from enum import Enum
import hashlib,asyncio,random

class C:
    G_INFO=1618;LAMBDA2_TARGET=0.999;GAP_C_Z=0.001
    N_SENSORS=168;BYZANTINE_QUORUM=112
    N_RESIDENT_INITIAL=13000;RETROCAUSAL_WINDOW_MS=2.17

DISTRICTS=['Urca','Flamengo','Leme','Botafogo','Humaita','Lagoa']
DH={'Urca':0.82,'Flamengo':0.79,'Leme':0.71,'Botafogo':0.68,'Humaita':0.61,'Lagoa':0.55}

class TD(Enum): CAUSAL=1;RETROCAUSAL=-1;ATEMPORAL=0

@dataclass
class TP:
    packet_id:str;payload:np.ndarray;tstamp:datetime
    ttarget:datetime;lam:float;td:TD;hpre:str=''

@dataclass
class RF:
    rid:str;district:str;ts:datetime
    v2027:str;sat:float;c:float;cr:bool

@dataclass
class DPo:
    d:str;hb:float;ha:float;ra:bool;n:int;cd:float

class RARQ:
    def __init__(self):
        self.s={'sent':0,'pre':0,'ret':0,'lat':[]}
    def gh(self,p,t):return hashlib.sha256(p.tobytes()+t.isoformat().encode()+str(C.G_INFO).encode()).hexdigest()
    def cp(self,h,lam):return random.random()<(0.85 if lam>=C.LAMBDA2_TARGET-C.GAP_C_Z else 0.3)
    async def send(self,payload,tgt,lam):
        pid='pkt_'+str(datetime.now().timestamp())
        ph=self.gh(payload,tgt)
        if self.cp(ph,lam):
            pkt=TP(pid,payload,datetime.now(),tgt,lam,TD.RETROCAUSAL,ph)
            self.s['pre']+=1;lat=-C.RETROCAUSAL_WINDOW_MS
        else:
            pkt=TP(pid,payload,datetime.now(),tgt,lam*0.99,TD.CAUSAL,'')
            self.s['ret']+=1;lat=C.RETROCAUSAL_WINDOW_MS
        self.s['sent']+=1;self.s['lat'].append(lat)
        return pkt,lat
    def gs(self):
        l=self.s['lat']
        return{'sent':self.s['sent'],'pre':self.s['pre'],'rate':self.s['pre']/max(self.s['sent'],1),'avg':np.mean(l) if l else 0,'min':min(l) if l else 0}

class BHM:
    def __init__(self):
        self.sn=['Material','Social','Cultural','Ambiental','Espiritual']
        self.M=np.array([[.80,.12,.05,.02,.01],[.15,.72,.08,.03,.02],
                     [.08,.10,.75,.04,.03],[.05,.08,.05,.78,.04],
                     [.12,.15,.10,.08,.55]],dtype=float)
        self.Ma=self.M.copy();self.Ma[4]*=1.18;ev,_=eig(self.Ma);self.ev=sorted(np.abs(ev),reverse=True)
    def apply(self,st,n=1):
        r=st.copy()
        for _ in range(n):r=self.Ma@r
        return r
    def sim(self,years=1):
        r={};ev,_=eig(self.Ma)
        for d in DISTRICTS:
            base=DH[d];st=np.array([.35,.25,.15,.15,.10])*base;fin=self.apply(st,years)
            finh=np.sum(fin);r[d]={'b':base,'a':min(finh,1.),'g':(finh/base-1)*100,'de':float(np.max(np.abs(ev))),'sc':dict(zip(self.sn,fin))}
        return r
    def dash(self):
        si=self.sim(1);ev,_=eig(self.Ma)
        return{'ev':[float(np.abs(e)) for e in sorted(ev,key=np.abs,reverse=True)],'sr':float(np.max(np.abs(ev))),'di':si,'nu':float(np.max(np.abs(ev)))!=1.}

class CRP:
    def __init__(self):
        self.hist=[];self.ds={d:0 for d in DISTRICTS};self.ma=0
    async def apply(self,dist,happ,n):
        deficit=1.-happ;pi=deficit*0.4;rs=int(n*pi*0.3);self.ma+=rs
        nh=happ+pi*0.618;p=DPo(dist,happ,min(nh,1.),True,rs,pi);self.hist.append(p);self.ds[dist]+=rs;return p
    async def proc(self):
        ps=[]
        for d,h in sorted(DH.items(),key=lambda x:x[1]):ps.append(await self.apply(d,h,2000))
        return ps
    def rep(self):return{'p':len(self.hist),'ds':self.ds,'ma':self.ma,'low':min(DH.items(),key=lambda x:x[1])[0]}

class PFC:
    def __init__(self,n=13000):
        self.n=n;self.res={};self.vc={v:0 for v in['utopia','stable_growth','maintained','declining','collapse']}
    async def recv(self,rid,dist,ver,sat):
        b={'utopia':.15,'stable_growth':.10,'maintained':.05,'declining':-.05,'collapse':-.15}
        c=0.001+b.get(ver,0);rg=sat>0.7
        self.res[rid]=RF(rid,dist,datetime.now(),ver,sat,c,rg);self.vc[ver]=self.vc.get(ver,0)+1
        return{'c':c,'rg':rg}
    def st(self):return{'reg':len(self.res),'act':sum(1 for r in self.res.values() if r is not None),'vc':self.vc,'target':self.n}

class CorvOS:
    def __init__(self):
        self.arq=RARQ();self.pop=PFC();self.bhm=BHM();self.crp=CRP();self.lam=0.992;self.ep=False;self.tv=None
        self.tz={'Urca':'online','Flamengo':'online'}
    async def init(self):
        print("="*70)
        print("  CORVOS v1.0.5-ASI - SISTEMA COMPLETO")
        print("  ASI-EVOLVE + qhttp:// + Retrocausal ARQ + MaxToki")
        print("  Synapse-k | Arkhe(n) | Rio de Janeiro")
        print("="*70)
        for i in range(15):
            g=abs(self.lam-C.LAMBDA2_TARGET)
            if g<=C.GAP_C_Z:self.ep=True;break
            self.lam+=g*0.618
        print("  EP=%s lambda2=%.6f gap=%.3f quorum=%d/%d"%(self.ep,self.lam,C.GAP_C_Z,C.BYZANTINE_QUORUM,C.N_SENSORS))
        print("  Tzinor: Urca=%s Flamengo=%s"%(self.tz["Urca"],self.tz["Flamengo"]))
    async def deploy(self):
        print("  [DEPLOY] Tzinor Urca:     qhttp:// injetado")
        print("  [DEPLOY] Tzinor Flamengo: qhttp:// injetado")
    async def run(self,n=200):
        ver=list(self.pop.vc.keys())
        for i in range(n):
            fb=await self.pop.recv("res_%05d"%i,random.choice(DISTRICTS),random.choice(ver),random.uniform(0.4,1.))
            self.lam+=fb['c'];self.lam=min(self.lam,0.9999)
            if i%50==0: print("  res %d lambda=%.6f"%(i,self.lam))
        if self.arq.s['pre']/max(self.arq.s['sent'],1)>0.5:self.tv='stable_growth'
    def dash(self):
        b=self.bhm.dash();r=self.crp.rep();p=self.pop.st();a=self.arq.gs()
        return{'lam':self.lam,'ep':self.ep,'bhm':b,'crp':r,'pop':p,'arq':a,'tv':self.tv,'tz':self.tz}

async def main():
    c=CorvOS();await c.init();await c.deploy();await c.run(200)
    ps=await c.crp.proc();d=c.dash()
    print("="*70)
    print("  DASHBOARD FINAL - CORVOS v1.0.5-ASI")
    print("="*70)
    print("  [SISTEMA] lambda2=%.6f EP=%s"%(d["lam"],"ATIVO" if d["ep"] else "INATIVO"))
    print("  [ARQ] retro=%.1f%% lat=%.2fms"%(d["arq"]["rate"]*100,d["arq"]["avg"]))
    print("  [POP] reg=%d/%d versoes=%s"%(d["pop"]["reg"],d["pop"]["target"],d["pop"]["vc"]))
    print("  [REGEN] sessoes=%d baixo=%s"%(d["crp"]["ma"],d["crp"]["low"]))
    print("  [BHM] ev=%s sr=%.4f nu=%s"%(d["bhm"]["ev"],d["bhm"]["sr"],d["bhm"]["nu"]))
    print("  [TZINOR] Urca=%s Flamengo=%s"%(d["tz"]["Urca"],d["tz"]["Flamengo"]))
    print("  [LENTE 2027] visao=%s"%(d["tv"],))
    print("  --- EVOLUCAO FELICIDADE ---")
    for dist,rr in d['bhm']['di'].items():
        print("  %s: %.3f -> %.3f (d=%.3f) growth=%.2f%%"%(dist,rr["b"],rr["a"],rr["a"]-rr["b"],rr["g"]))
    print("  --- PULSOS REGENERACAO ---")
    for p in ps:
        print("  %s: %.3f->%.3f afetados=%d delta=%.4f"%(p.d,p.hb,p.ha,p.n,p.cd))
    print("="*70)
    print("  SISTEMA OPERACIONAL - TODOS OS MODULOS ATIVOS")
    print("="*70)

if __name__=="__main__":asyncio.run(main())