from datetime import datetime, timezone, timedelta

def _dt(s):
    if not s: return None
    return datetime.fromisoformat(s.replace('Z','+00:00'))

def evaluate(c, now='2026-09-16T08:00:00Z'):
    now_dt=_dt(now)
    retrieved=_dt(c.get('evidence_retrieved_at'))
    age_days=((now_dt-retrieved).total_seconds()/86400) if retrieved else 9999
    evidence_fresh = age_days <= 30
    provenance_complete=bool(c.get('provenance_ref'))
    auth_ok=c.get('auth_state')=='VALID'
    quota_fields=[c.get('quota_model'),c.get('method_or_operation')]
    quota_evidence_valid=all(x not in (None,'','UNKNOWN') for x in quota_fields)
    bucket_model_valid=bool(c.get('bucket_model_current')) and bool(c.get('quota_bucket'))

    # precedence: provenance/freshness -> auth -> account/policy -> permission -> quota/rate -> allow
    if not provenance_complete:
        health='UNKNOWN'; action='BLOCKED'; recheck='REFRESH_EVIDENCE_NOW'; reason='PROVENANCE_MISSING'
    elif not evidence_fresh:
        health='STALE_EVIDENCE'; action='BLOCKED'; recheck='REFRESH_EVIDENCE_NOW'; reason='DECISIVE_EVIDENCE_STALE'
    elif not auth_ok:
        health='AUTH_REQUIRED'; action='REAUTH_REQUIRED'; recheck='AFTER_REAUTH'; reason='AUTH_NOT_VALID'
    elif c.get('account_restriction_state') not in ('NONE',None):
        health='POLICY_RESTRICTED'; action='POLICY_REVIEW'; recheck='AFTER_POLICY_REVIEW'; reason='ACCOUNT_RESTRICTION_ACTIVE'
    elif c.get('permission_state')!='ALLOWED':
        health='PERMISSION_BLOCKED'; action='POLICY_REVIEW'; recheck='AFTER_PERMISSION_REVIEW'; reason='OPERATION_PERMISSION_DENIED'
    elif not bucket_model_valid:
        health='AMBIGUOUS'; action='QUOTA_REVIEW'; recheck='REFRESH_QUOTA_MODEL_NOW'; reason='QUOTA_BUCKET_MODEL_NOT_CURRENT'
    elif c.get('rate_limit_class')=='SECONDARY' and c.get('http_status') in (403,429):
        ra=c.get('retry_after')
        if ra is not None:
            recheck=(_dt(now)+timedelta(seconds=int(ra))).isoformat().replace('+00:00','Z')
        elif c.get('reset_at'):
            recheck=c['reset_at']
        else:
            recheck='PROVIDER_BACKOFF_REVIEW'
        health='RATE_LIMITED'; action='DEFER_UNTIL_RESET'; reason='SECONDARY_RATE_LIMIT_ACTIVE'
    elif c.get('remaining_value') == 0 and c.get('rate_limit_class')=='PRIMARY':
        health='RATE_LIMITED'; action='DEFER_UNTIL_RESET'; recheck=c.get('reset_at') or 'REFRESH_RATE_LIMIT'; reason='PRIMARY_RATE_LIMIT_EXHAUSTED'
    elif c.get('provider_error_code')=='quotaExceeded' or (c.get('remaining_value')==0 and c.get('rate_limit_class')=='QUOTA'):
        health='QUOTA_EXHAUSTED'; action='QUOTA_REVIEW'; recheck=c.get('reset_at') or 'QUOTA_REVIEW_REQUIRED'; reason='PROVIDER_QUOTA_EXHAUSTED'
    else:
        health='HEALTHY'; action='ALLOW'; recheck=c.get('reset_at') or 'ON_NEXT_PROVIDER_SIGNAL'; reason='EVIDENCE_SUPPORTS_BOUNDED_ACTION'
    return {
      'health_state':health,
      'allowed_action':action,
      'recheck_at':recheck,
      'auth_ok':auth_ok,
      'quota_evidence_valid':quota_evidence_valid,
      'bucket_model_valid':bucket_model_valid,
      'evidence_fresh':evidence_fresh,
      'control_reason':reason
    }
